1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 package dom;
19 
20 import java.io.OutputStream;
21 import java.io.OutputStreamWriter;
22 import java.io.PrintWriter;
23 import java.io.UnsupportedEncodingException;
24 import java.lang.reflect.Method;
25 
26 import org.w3c.dom.Attr;
27 import org.w3c.dom.Document;
28 import org.w3c.dom.DocumentType;
29 import org.w3c.dom.NamedNodeMap;
30 import org.w3c.dom.Node;
31 import org.xml.sax.SAXException;
32 import org.xml.sax.SAXParseException;
33 
34 /**
35  * A sample DOM writer. This sample program illustrates how to
36  * traverse a DOM tree in order to print a document that is parsed.
37  *
38  * @author Andy Clark, IBM
39  *
40  * @version $Id: Writer.java 447683 2006-09-19 02:36:31Z mrglavas $
41  */
42 public class Writer {
43 
44     //
45     // Constants
46     //
47 
48     // feature ids
49 
50     /** Namespaces feature id (http://xml.org/sax/features/namespaces). */
51     protected static final String NAMESPACES_FEATURE_ID = "http://xml.org/sax/features/namespaces";
52 
53     /** Validation feature id (http://xml.org/sax/features/validation). */
54     protected static final String VALIDATION_FEATURE_ID = "http://xml.org/sax/features/validation";
55 
56     /** Schema validation feature id (http://apache.org/xml/features/validation/schema). */
57     protected static final String SCHEMA_VALIDATION_FEATURE_ID = "http://apache.org/xml/features/validation/schema";
58 
59     /** Schema full checking feature id (http://apache.org/xml/features/validation/schema-full-checking). */
60     protected static final String SCHEMA_FULL_CHECKING_FEATURE_ID = "http://apache.org/xml/features/validation/schema-full-checking";
61 
62     /** Honour all schema locations feature id (http://apache.org/xml/features/honour-all-schemaLocations). */
63     protected static final String HONOUR_ALL_SCHEMA_LOCATIONS_ID = "http://apache.org/xml/features/honour-all-schemaLocations";
64 
65     /** Validate schema annotations feature id (http://apache.org/xml/features/validate-annotations). */
66     protected static final String VALIDATE_ANNOTATIONS_ID = "http://apache.org/xml/features/validate-annotations";
67 
68     /** Generate synthetic schema annotations feature id (http://apache.org/xml/features/generate-synthetic-annotations). */
69     protected static final String GENERATE_SYNTHETIC_ANNOTATIONS_ID = "http://apache.org/xml/features/generate-synthetic-annotations";
70 
71     /** Dynamic validation feature id (http://apache.org/xml/features/validation/dynamic). */
72     protected static final String DYNAMIC_VALIDATION_FEATURE_ID = "http://apache.org/xml/features/validation/dynamic";
73 
74     /** Load external DTD feature id (http://apache.org/xml/features/nonvalidating/load-external-dtd). */
75     protected static final String LOAD_EXTERNAL_DTD_FEATURE_ID = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
76 
77     /** XInclude feature id (http://apache.org/xml/features/xinclude). */
78     protected static final String XINCLUDE_FEATURE_ID = "http://apache.org/xml/features/xinclude";
79 
80     /** XInclude fixup base URIs feature id (http://apache.org/xml/features/xinclude/fixup-base-uris). */
81     protected static final String XINCLUDE_FIXUP_BASE_URIS_FEATURE_ID = "http://apache.org/xml/features/xinclude/fixup-base-uris";
82 
83     /** XInclude fixup language feature id (http://apache.org/xml/features/xinclude/fixup-language). */
84     protected static final String XINCLUDE_FIXUP_LANGUAGE_FEATURE_ID = "http://apache.org/xml/features/xinclude/fixup-language";
85 
86     // default settings
87 
88     /** Default parser name. */
89     protected static final String DEFAULT_PARSER_NAME = "dom.wrappers.Xerces";
90 
91     /** Default namespaces support (true). */
92     protected static final boolean DEFAULT_NAMESPACES = true;
93 
94     /** Default validation support (false). */
95     protected static final boolean DEFAULT_VALIDATION = false;
96 
97     /** Default load external DTD (true). */
98     protected static final boolean DEFAULT_LOAD_EXTERNAL_DTD = true;
99 
100     /** Default Schema validation support (false). */
101     protected static final boolean DEFAULT_SCHEMA_VALIDATION = false;
102 
103     /** Default Schema full checking support (false). */
104     protected static final boolean DEFAULT_SCHEMA_FULL_CHECKING = false;
105 
106     /** Default honour all schema locations (false). */
107     protected static final boolean DEFAULT_HONOUR_ALL_SCHEMA_LOCATIONS = false;
108 
109     /** Default validate schema annotations (false). */
110     protected static final boolean DEFAULT_VALIDATE_ANNOTATIONS = false;
111 
112     /** Default generate synthetic schema annotations (false). */
113     protected static final boolean DEFAULT_GENERATE_SYNTHETIC_ANNOTATIONS = false;
114 
115     /** Default dynamic validation support (false). */
116     protected static final boolean DEFAULT_DYNAMIC_VALIDATION = false;
117 
118     /** Default XInclude processing support (false). */
119     protected static final boolean DEFAULT_XINCLUDE = false;
120 
121     /** Default XInclude fixup base URIs support (true). */
122     protected static final boolean DEFAULT_XINCLUDE_FIXUP_BASE_URIS = true;
123 
124     /** Default XInclude fixup language support (true). */
125     protected static final boolean DEFAULT_XINCLUDE_FIXUP_LANGUAGE = true;
126 
127     /** Default canonical output (false). */
128     protected static final boolean DEFAULT_CANONICAL = false;
129 
130     //
131     // Data
132     //
133 
134     /** Print writer. */
135     protected PrintWriter fOut;
136 
137     /** Canonical output. */
138     protected boolean fCanonical;
139 
140     /** Processing XML 1.1 document. */
141     protected boolean fXML11;
142 
143     //
144     // Constructors
145     //
146 
147     /** Default constructor. */
Writer()148     public Writer() {
149     } // <init>()
150 
Writer(boolean canonical)151     public Writer(boolean canonical) {
152         fCanonical = canonical;
153     } // <init>(boolean)
154 
155     //
156     // Public methods
157     //
158 
159     /** Sets whether output is canonical. */
setCanonical(boolean canonical)160     public void setCanonical(boolean canonical) {
161         fCanonical = canonical;
162     } // setCanonical(boolean)
163 
164     /** Sets the output stream for printing. */
setOutput(OutputStream stream, String encoding)165     public void setOutput(OutputStream stream, String encoding)
166         throws UnsupportedEncodingException {
167 
168         if (encoding == null) {
169             encoding = "UTF8";
170         }
171 
172         java.io.Writer writer = new OutputStreamWriter(stream, encoding);
173         fOut = new PrintWriter(writer);
174 
175     } // setOutput(OutputStream,String)
176 
177     /** Sets the output writer. */
setOutput(java.io.Writer writer)178     public void setOutput(java.io.Writer writer) {
179 
180         fOut = writer instanceof PrintWriter
181              ? (PrintWriter)writer : new PrintWriter(writer);
182 
183     } // setOutput(java.io.Writer)
184 
185     /** Writes the specified node, recursively. */
write(Node node)186     public void write(Node node) {
187 
188         // is there anything to do?
189         if (node == null) {
190             return;
191         }
192 
193         short type = node.getNodeType();
194         switch (type) {
195             case Node.DOCUMENT_NODE: {
196                 Document document = (Document)node;
197                 fXML11 = "1.1".equals(getVersion(document));
198                 if (!fCanonical) {
199                     if (fXML11) {
200                         fOut.println("<?xml version=\"1.1\" encoding=\"UTF-8\"?>");
201                     }
202                     else {
203                         fOut.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
204                     }
205                     fOut.flush();
206                     write(document.getDoctype());
207                 }
208                 write(document.getDocumentElement());
209                 break;
210             }
211 
212             case Node.DOCUMENT_TYPE_NODE: {
213                 DocumentType doctype = (DocumentType)node;
214                 fOut.print("<!DOCTYPE ");
215                 fOut.print(doctype.getName());
216                 String publicId = doctype.getPublicId();
217                 String systemId = doctype.getSystemId();
218                 if (publicId != null) {
219                     fOut.print(" PUBLIC '");
220                     fOut.print(publicId);
221                     fOut.print("' '");
222                     fOut.print(systemId);
223                     fOut.print('\'');
224                 }
225                 else if (systemId != null) {
226                     fOut.print(" SYSTEM '");
227                     fOut.print(systemId);
228                     fOut.print('\'');
229                 }
230                 String internalSubset = doctype.getInternalSubset();
231                 if (internalSubset != null) {
232                     fOut.println(" [");
233                     fOut.print(internalSubset);
234                     fOut.print(']');
235                 }
236                 fOut.println('>');
237                 break;
238             }
239 
240             case Node.ELEMENT_NODE: {
241                 fOut.print('<');
242                 fOut.print(node.getNodeName());
243                 Attr attrs[] = sortAttributes(node.getAttributes());
244                 for (int i = 0; i < attrs.length; i++) {
245                     Attr attr = attrs[i];
246                     fOut.print(' ');
247                     fOut.print(attr.getNodeName());
248                     fOut.print("=\"");
249                     normalizeAndPrint(attr.getNodeValue(), true);
250                     fOut.print('"');
251                 }
252                 fOut.print('>');
253                 fOut.flush();
254 
255                 Node child = node.getFirstChild();
256                 while (child != null) {
257                     write(child);
258                     child = child.getNextSibling();
259                 }
260                 break;
261             }
262 
263             case Node.ENTITY_REFERENCE_NODE: {
264                 if (fCanonical) {
265                     Node child = node.getFirstChild();
266                     while (child != null) {
267                         write(child);
268                         child = child.getNextSibling();
269                     }
270                 }
271                 else {
272                     fOut.print('&');
273                     fOut.print(node.getNodeName());
274                     fOut.print(';');
275                     fOut.flush();
276                 }
277                 break;
278             }
279 
280             case Node.CDATA_SECTION_NODE: {
281                 if (fCanonical) {
282                     normalizeAndPrint(node.getNodeValue(), false);
283                 }
284                 else {
285                     fOut.print("<![CDATA[");
286                     fOut.print(node.getNodeValue());
287                     fOut.print("]]>");
288                 }
289                 fOut.flush();
290                 break;
291             }
292 
293             case Node.TEXT_NODE: {
294                 normalizeAndPrint(node.getNodeValue(), false);
295                 fOut.flush();
296                 break;
297             }
298 
299             case Node.PROCESSING_INSTRUCTION_NODE: {
300                 fOut.print("<?");
301                 fOut.print(node.getNodeName());
302                 String data = node.getNodeValue();
303                 if (data != null && data.length() > 0) {
304                     fOut.print(' ');
305                     fOut.print(data);
306                 }
307                 fOut.print("?>");
308                 fOut.flush();
309                 break;
310             }
311 
312             case Node.COMMENT_NODE: {
313                 if (!fCanonical) {
314                     fOut.print("<!--");
315                     String comment = node.getNodeValue();
316                     if (comment != null && comment.length() > 0) {
317                         fOut.print(comment);
318                     }
319                     fOut.print("-->");
320                     fOut.flush();
321                 }
322             }
323         }
324 
325         if (type == Node.ELEMENT_NODE) {
326             fOut.print("</");
327             fOut.print(node.getNodeName());
328             fOut.print('>');
329             fOut.flush();
330         }
331 
332     } // write(Node)
333 
334     /** Returns a sorted list of attributes. */
sortAttributes(NamedNodeMap attrs)335     protected Attr[] sortAttributes(NamedNodeMap attrs) {
336 
337         int len = (attrs != null) ? attrs.getLength() : 0;
338         Attr array[] = new Attr[len];
339         for (int i = 0; i < len; i++) {
340             array[i] = (Attr)attrs.item(i);
341         }
342         for (int i = 0; i < len - 1; i++) {
343             String name = array[i].getNodeName();
344             int index = i;
345             for (int j = i + 1; j < len; j++) {
346                 String curName = array[j].getNodeName();
347                 if (curName.compareTo(name) < 0) {
348                     name = curName;
349                     index = j;
350                 }
351             }
352             if (index != i) {
353                 Attr temp = array[i];
354                 array[i] = array[index];
355                 array[index] = temp;
356             }
357         }
358 
359         return array;
360 
361     } // sortAttributes(NamedNodeMap):Attr[]
362 
363     //
364     // Protected methods
365     //
366 
367     /** Normalizes and prints the given string. */
normalizeAndPrint(String s, boolean isAttValue)368     protected void normalizeAndPrint(String s, boolean isAttValue) {
369 
370         int len = (s != null) ? s.length() : 0;
371         for (int i = 0; i < len; i++) {
372             char c = s.charAt(i);
373             normalizeAndPrint(c, isAttValue);
374         }
375 
376     } // normalizeAndPrint(String,boolean)
377 
378     /** Normalizes and print the given character. */
normalizeAndPrint(char c, boolean isAttValue)379     protected void normalizeAndPrint(char c, boolean isAttValue) {
380 
381         switch (c) {
382             case '<': {
383                 fOut.print("&lt;");
384                 break;
385             }
386             case '>': {
387                 fOut.print("&gt;");
388                 break;
389             }
390             case '&': {
391                 fOut.print("&amp;");
392                 break;
393             }
394             case '"': {
395                 // A '"' that appears in character data
396                 // does not need to be escaped.
397                 if (isAttValue) {
398                     fOut.print("&quot;");
399                 }
400                 else {
401                     fOut.print("\"");
402                 }
403                 break;
404             }
405             case '\r': {
406             	// If CR is part of the document's content, it
407             	// must not be printed as a literal otherwise
408             	// it would be normalized to LF when the document
409             	// is reparsed.
410             	fOut.print("&#xD;");
411             	break;
412             }
413             case '\n': {
414                 if (fCanonical) {
415                     fOut.print("&#xA;");
416                     break;
417                 }
418                 // else, default print char
419             }
420             default: {
421             	// In XML 1.1, control chars in the ranges [#x1-#x1F, #x7F-#x9F] must be escaped.
422             	//
423             	// Escape space characters that would be normalized to #x20 in attribute values
424             	// when the document is reparsed.
425             	//
426             	// Escape NEL (0x85) and LSEP (0x2028) that appear in content
427             	// if the document is XML 1.1, since they would be normalized to LF
428             	// when the document is reparsed.
429             	if (fXML11 && ((c >= 0x01 && c <= 0x1F && c != 0x09 && c != 0x0A)
430             	    || (c >= 0x7F && c <= 0x9F) || c == 0x2028)
431             	    || isAttValue && (c == 0x09 || c == 0x0A)) {
432             	    fOut.print("&#x");
433             	    fOut.print(Integer.toHexString(c).toUpperCase());
434             	    fOut.print(";");
435                 }
436                 else {
437                     fOut.print(c);
438                 }
439             }
440         }
441     } // normalizeAndPrint(char,boolean)
442 
443     /** Extracts the XML version from the Document. */
getVersion(Document document)444     protected String getVersion(Document document) {
445     	if (document == null) {
446     	    return null;
447     	}
448         String version = null;
449         Method getXMLVersion = null;
450         try {
451             getXMLVersion = document.getClass().getMethod("getXmlVersion", new Class[]{});
452             // If Document class implements DOM L3, this method will exist.
453             if (getXMLVersion != null) {
454                 version = (String) getXMLVersion.invoke(document, (Object[]) null);
455             }
456         }
457         catch (Exception e) {
458             // Either this locator object doesn't have
459             // this method, or we're on an old JDK.
460         }
461         return version;
462     } // getVersion(Document)
463 
464     //
465     // Main
466     //
467 
468     /** Main program entry point. */
main(String argv[])469     public static void main(String argv[]) {
470 
471         // is there anything to do?
472         if (argv.length == 0) {
473             printUsage();
474             System.exit(1);
475         }
476 
477         // variables
478         Writer writer = null;
479         ParserWrapper parser = null;
480         boolean namespaces = DEFAULT_NAMESPACES;
481         boolean validation = DEFAULT_VALIDATION;
482         boolean externalDTD = DEFAULT_LOAD_EXTERNAL_DTD;
483         boolean schemaValidation = DEFAULT_SCHEMA_VALIDATION;
484         boolean schemaFullChecking = DEFAULT_SCHEMA_FULL_CHECKING;
485         boolean honourAllSchemaLocations = DEFAULT_HONOUR_ALL_SCHEMA_LOCATIONS;
486         boolean validateAnnotations = DEFAULT_VALIDATE_ANNOTATIONS;
487         boolean generateSyntheticAnnotations = DEFAULT_GENERATE_SYNTHETIC_ANNOTATIONS;
488         boolean dynamicValidation = DEFAULT_DYNAMIC_VALIDATION;
489         boolean xincludeProcessing = DEFAULT_XINCLUDE;
490         boolean xincludeFixupBaseURIs = DEFAULT_XINCLUDE_FIXUP_BASE_URIS;
491         boolean xincludeFixupLanguage = DEFAULT_XINCLUDE_FIXUP_LANGUAGE;
492         boolean canonical = DEFAULT_CANONICAL;
493 
494         // process arguments
495         for (int i = 0; i < argv.length; i++) {
496             String arg = argv[i];
497             if (arg.startsWith("-")) {
498                 String option = arg.substring(1);
499                 if (option.equals("p")) {
500                     // get parser name
501                     if (++i == argv.length) {
502                         System.err.println("error: Missing argument to -p option.");
503                     }
504                     String parserName = argv[i];
505 
506                     // create parser
507                     try {
508                         parser = (ParserWrapper)Class.forName(parserName).newInstance();
509                     }
510                     catch (Exception e) {
511                         parser = null;
512                         System.err.println("error: Unable to instantiate parser ("+parserName+")");
513                     }
514                     continue;
515                 }
516                 if (option.equalsIgnoreCase("n")) {
517                     namespaces = option.equals("n");
518                     continue;
519                 }
520                 if (option.equalsIgnoreCase("v")) {
521                     validation = option.equals("v");
522                     continue;
523                 }
524                 if (option.equalsIgnoreCase("xd")) {
525                     externalDTD = option.equals("xd");
526                     continue;
527                 }
528                 if (option.equalsIgnoreCase("s")) {
529                     schemaValidation = option.equals("s");
530                     continue;
531                 }
532                 if (option.equalsIgnoreCase("f")) {
533                     schemaFullChecking = option.equals("f");
534                     continue;
535                 }
536                 if (option.equalsIgnoreCase("hs")) {
537                     honourAllSchemaLocations = option.equals("hs");
538                     continue;
539                 }
540                 if (option.equalsIgnoreCase("va")) {
541                     validateAnnotations = option.equals("va");
542                     continue;
543                 }
544                 if (option.equalsIgnoreCase("ga")) {
545                     generateSyntheticAnnotations = option.equals("ga");
546                     continue;
547                 }
548                 if (option.equalsIgnoreCase("dv")) {
549                     dynamicValidation = option.equals("dv");
550                     continue;
551                 }
552                 if (option.equalsIgnoreCase("xi")) {
553                     xincludeProcessing = option.equals("xi");
554                     continue;
555                 }
556                 if (option.equalsIgnoreCase("xb")) {
557                     xincludeFixupBaseURIs = option.equals("xb");
558                     continue;
559                 }
560                 if (option.equalsIgnoreCase("xl")) {
561                     xincludeFixupLanguage = option.equals("xl");
562                     continue;
563                 }
564                 if (option.equalsIgnoreCase("c")) {
565                     canonical = option.equals("c");
566                     continue;
567                 }
568                 if (option.equals("h")) {
569                     printUsage();
570                     continue;
571                 }
572             }
573 
574             // use default parser?
575             if (parser == null) {
576 
577                 // create parser
578                 try {
579                     parser = (ParserWrapper)Class.forName(DEFAULT_PARSER_NAME).newInstance();
580                 }
581                 catch (Exception e) {
582                     System.err.println("error: Unable to instantiate parser ("+DEFAULT_PARSER_NAME+")");
583                     continue;
584                 }
585             }
586 
587             // set parser features
588             try {
589                 parser.setFeature(NAMESPACES_FEATURE_ID, namespaces);
590             }
591             catch (SAXException e) {
592                 System.err.println("warning: Parser does not support feature ("+NAMESPACES_FEATURE_ID+")");
593             }
594             try {
595                 parser.setFeature(VALIDATION_FEATURE_ID, validation);
596             }
597             catch (SAXException e) {
598                 System.err.println("warning: Parser does not support feature ("+VALIDATION_FEATURE_ID+")");
599             }
600             try {
601                 parser.setFeature(LOAD_EXTERNAL_DTD_FEATURE_ID, externalDTD);
602             }
603             catch (SAXException e) {
604                 System.err.println("warning: Parser does not support feature ("+LOAD_EXTERNAL_DTD_FEATURE_ID+")");
605             }
606             try {
607                 parser.setFeature(SCHEMA_VALIDATION_FEATURE_ID, schemaValidation);
608             }
609             catch (SAXException e) {
610                 System.err.println("warning: Parser does not support feature ("+SCHEMA_VALIDATION_FEATURE_ID+")");
611             }
612             try {
613                 parser.setFeature(SCHEMA_FULL_CHECKING_FEATURE_ID, schemaFullChecking);
614             }
615             catch (SAXException e) {
616                 System.err.println("warning: Parser does not support feature ("+SCHEMA_FULL_CHECKING_FEATURE_ID+")");
617             }
618             try {
619                 parser.setFeature(HONOUR_ALL_SCHEMA_LOCATIONS_ID, honourAllSchemaLocations);
620             }
621             catch (SAXException e) {
622                 System.err.println("warning: Parser does not support feature ("+HONOUR_ALL_SCHEMA_LOCATIONS_ID+")");
623             }
624             try {
625                 parser.setFeature(VALIDATE_ANNOTATIONS_ID, validateAnnotations);
626             }
627             catch (SAXException e) {
628                 System.err.println("warning: Parser does not support feature ("+VALIDATE_ANNOTATIONS_ID+")");
629             }
630             try {
631                 parser.setFeature(GENERATE_SYNTHETIC_ANNOTATIONS_ID, generateSyntheticAnnotations);
632             }
633             catch (SAXException e) {
634                 System.err.println("warning: Parser does not support feature ("+GENERATE_SYNTHETIC_ANNOTATIONS_ID+")");
635             }
636             try {
637                 parser.setFeature(DYNAMIC_VALIDATION_FEATURE_ID, dynamicValidation);
638             }
639             catch (SAXException e) {
640                 System.err.println("warning: Parser does not support feature ("+DYNAMIC_VALIDATION_FEATURE_ID+")");
641             }
642             try {
643                 parser.setFeature(XINCLUDE_FEATURE_ID, xincludeProcessing);
644             }
645             catch (SAXException e) {
646                 System.err.println("warning: Parser does not support feature ("+XINCLUDE_FEATURE_ID+")");
647             }
648             try {
649                 parser.setFeature(XINCLUDE_FIXUP_BASE_URIS_FEATURE_ID, xincludeFixupBaseURIs);
650             }
651             catch (SAXException e) {
652                 System.err.println("warning: Parser does not support feature ("+XINCLUDE_FIXUP_BASE_URIS_FEATURE_ID+")");
653             }
654             try {
655                 parser.setFeature(XINCLUDE_FIXUP_LANGUAGE_FEATURE_ID, xincludeFixupLanguage);
656             }
657             catch (SAXException e) {
658                 System.err.println("warning: Parser does not support feature ("+XINCLUDE_FIXUP_LANGUAGE_FEATURE_ID+")");
659             }
660 
661             // setup writer
662             if (writer == null) {
663                 writer = new Writer();
664                 try {
665                     writer.setOutput(System.out, "UTF8");
666                 }
667                 catch (UnsupportedEncodingException e) {
668                     System.err.println("error: Unable to set output. Exiting.");
669                     System.exit(1);
670                 }
671             }
672 
673             // parse file
674             writer.setCanonical(canonical);
675             try {
676                 Document document = parser.parse(arg);
677                 writer.write(document);
678             }
679             catch (SAXParseException e) {
680                 // ignore
681             }
682             catch (Exception e) {
683                 System.err.println("error: Parse error occurred - "+e.getMessage());
684                 if (e instanceof SAXException) {
685                     Exception nested = ((SAXException)e).getException();
686                     if (nested != null) {
687                         e = nested;
688                     }
689                 }
690                 e.printStackTrace(System.err);
691             }
692         }
693 
694     } // main(String[])
695 
696     //
697     // Private static methods
698     //
699 
700     /** Prints the usage. */
printUsage()701     private static void printUsage() {
702 
703         System.err.println("usage: java dom.Writer (options) uri ...");
704         System.err.println();
705 
706         System.err.println("options:");
707         System.err.println("  -p name     Select parser by name.");
708         System.err.println("  -n | -N     Turn on/off namespace processing.");
709         System.err.println("  -v | -V     Turn on/off validation.");
710         System.err.println("  -xd | -XD   Turn on/off loading of external DTDs.");
711         System.err.println("              NOTE: Always on when -v in use and not supported by all parsers.");
712         System.err.println("  -s | -S     Turn on/off Schema validation support.");
713         System.err.println("              NOTE: Not supported by all parsers.");
714         System.err.println("  -f  | -F    Turn on/off Schema full checking.");
715         System.err.println("              NOTE: Requires use of -s and not supported by all parsers.");
716         System.err.println("  -hs | -HS   Turn on/off honouring of all schema locations.");
717         System.err.println("              NOTE: Requires use of -s and not supported by all parsers.");
718         System.err.println("  -va | -VA   Turn on/off validation of schema annotations.");
719         System.err.println("              NOTE: Requires use of -s and not supported by all parsers.");
720         System.err.println("  -ga | -GA   Turn on/off generation of synthetic schema annotations.");
721         System.err.println("              NOTE: Requires use of -s and not supported by all parsers.");
722         System.err.println("  -dv | -DV   Turn on/off dynamic validation.");
723         System.err.println("              NOTE: Not supported by all parsers.");
724         System.err.println("  -xi | -XI   Turn on/off XInclude processing.");
725         System.err.println("              NOTE: Not supported by all parsers.");
726         System.err.println("  -xb | -XB   Turn on/off base URI fixup during XInclude processing.");
727         System.err.println("              NOTE: Requires use of -xi and not supported by all parsers.");
728         System.err.println("  -xl | -XL   Turn on/off language fixup during XInclude processing.");
729         System.err.println("              NOTE: Requires use of -xi and not supported by all parsers.");
730         System.err.println("  -c | -C     Turn on/off Canonical XML output.");
731         System.err.println("              NOTE: This is not W3C canonical output.");
732         System.err.println("  -h          This help screen.");
733         System.err.println();
734 
735         System.err.println("defaults:");
736         System.err.println("  Parser:     "+DEFAULT_PARSER_NAME);
737         System.err.print("  Namespaces: ");
738         System.err.println(DEFAULT_NAMESPACES ? "on" : "off");
739         System.err.print("  Validation: ");
740         System.err.println(DEFAULT_VALIDATION ? "on" : "off");
741         System.err.print("  Load External DTD: ");
742         System.err.println(DEFAULT_LOAD_EXTERNAL_DTD ? "on" : "off");
743         System.err.print("  Schema:     ");
744         System.err.println(DEFAULT_SCHEMA_VALIDATION ? "on" : "off");
745         System.err.print("  Schema full checking:     ");
746         System.err.println(DEFAULT_SCHEMA_FULL_CHECKING ? "on" : "off");
747         System.err.print("  Dynamic:    ");
748         System.err.println(DEFAULT_DYNAMIC_VALIDATION ? "on" : "off");
749         System.err.print("  Canonical:  ");
750         System.err.println(DEFAULT_CANONICAL ? "on" : "off");
751         System.err.print("  Honour all schema locations:       ");
752         System.err.println(DEFAULT_HONOUR_ALL_SCHEMA_LOCATIONS ? "on" : "off");
753         System.err.print("  Validate Annotations:              ");
754         System.err.println(DEFAULT_VALIDATE_ANNOTATIONS ? "on" : "off");
755         System.err.print("  Generate Synthetic Annotations:    ");
756         System.err.println(DEFAULT_GENERATE_SYNTHETIC_ANNOTATIONS ? "on" : "off");
757         System.err.print("  XInclude:   ");
758         System.err.println(DEFAULT_XINCLUDE ? "on" : "off");
759         System.err.print("  XInclude base URI fixup:  ");
760         System.err.println(DEFAULT_XINCLUDE_FIXUP_BASE_URIS ? "on" : "off");
761         System.err.print("  XInclude language fixup:  ");
762         System.err.println(DEFAULT_XINCLUDE_FIXUP_LANGUAGE ? "on" : "off");
763 
764     } // printUsage()
765 
766 }  // class Writer
767