< prev index next >

src/java.xml.bind/share/classes/com/sun/xml/internal/txw2/output/XMLWriter.java

Print this page




  76  * <pre>
  77  * w.startElement("", "foo", "", new AttributesImpl());
  78  * </pre>
  79  *
  80  * <p>Except that it is more efficient because it does not allocate
  81  * a new empty attribute list each time.  The following code will send
  82  * a simple XML document to standard output:</p>
  83  *
  84  * <pre>
  85  * XMLWriter w = new XMLWriter();
  86  *
  87  * w.startDocument();
  88  * w.startElement("greeting");
  89  * w.characters("Hello, world!");
  90  * w.endElement("greeting");
  91  * w.endDocument();
  92  * </pre>
  93  *
  94  * <p>The resulting document will look like this:</p>
  95  *
  96  * <pre>
  97  * &lt;?xml version="1.0" standalone="yes"?>
  98  *
  99  * &lt;greeting>Hello, world!&lt;/greeting>
 100  * </pre>
 101  *
 102  * <p>In fact, there is an even simpler convenience method,
 103  * <var>dataElement</var>, designed for writing elements that
 104  * contain only character data, so the code to generate the
 105  * document could be shortened to</p>
 106  *
 107  * <pre>
 108  * XMLWriter w = new XMLWriter();
 109  *
 110  * w.startDocument();
 111  * w.dataElement("greeting", "Hello, world!");
 112  * w.endDocument();
 113  * </pre>
 114  *
 115  * <h2>Whitespace</h2>
 116  *
 117  * <p>According to the XML Recommendation, <em>all</em> whitespace
 118  * in an XML document is potentially significant to an application,
 119  * so this class never adds newlines or indentation.  If you
 120  * insert three elements in a row, as in</p>
 121  *
 122  * <pre>
 123  * w.dataElement("item", "1");
 124  * w.dataElement("item", "2");
 125  * w.dataElement("item", "3");
 126  * </pre>
 127  *
 128  * <p>you will end up with</p>
 129  *
 130  * <pre>
 131  * &lt;item>1&lt;/item>&lt;item>3&lt;/item>&lt;item>3&lt;/item>
 132  * </pre>
 133  *
 134  * <p>You need to invoke one of the <var>characters</var> methods
 135  * explicitly to add newlines or indentation.  Alternatively, you
 136  * can use {@link DataWriter}, which
 137  * is derived from this class -- it is optimized for writing
 138  * purely data-oriented (or field-oriented) XML, and does automatic
 139  * linebreaks and indentation (but does not support mixed content
 140  * properly).</p>
 141  *
 142  *
 143  * <h2>Namespace Support</h2>
 144  *
 145  * <p>The writer contains extensive support for XML Namespaces, so that
 146  * a client application does not have to keep track of prefixes and
 147  * supply <var>xmlns</var> attributes.  By default, the XML writer will
 148  * generate Namespace declarations in the form _NS1, _NS2, etc., wherever
 149  * they are needed, as in the following example:</p>
 150  *
 151  * <pre>
 152  * w.startDocument();
 153  * w.emptyElement("http://www.foo.com/ns/", "foo");
 154  * w.endDocument();
 155  * </pre>
 156  *
 157  * <p>The resulting document will look like this:</p>
 158  *
 159  * <pre>
 160  * &lt;?xml version="1.0" standalone="yes"?>
 161  *
 162  * &lt;_NS1:foo xmlns:_NS1="http://www.foo.com/ns/"/>
 163  * </pre>
 164  *
 165  * <p>In many cases, document authors will prefer to choose their
 166  * own prefixes rather than using the (ugly) default names.  The
 167  * XML writer allows two methods for selecting prefixes:</p>
 168  *
 169  * <ol>
 170  * <li>the qualified name</li>
 171  * <li>the {@link #setPrefix setPrefix} method.</li>
 172  * </ol>
 173  *
 174  * <p>Whenever the XML writer finds a new Namespace URI, it checks
 175  * to see if a qualified (prefixed) name is also available; if so
 176  * it attempts to use the name's prefix (as long as the prefix is
 177  * not already in use for another Namespace URI).</p>
 178  *
 179  * <p>Before writing a document, the client can also pre-map a prefix
 180  * to a Namespace URI with the setPrefix method:</p>
 181  *
 182  * <pre>
 183  * w.setPrefix("http://www.foo.com/ns/", "foo");
 184  * w.startDocument();
 185  * w.emptyElement("http://www.foo.com/ns/", "foo");
 186  * w.endDocument();
 187  * </pre>
 188  *
 189  * <p>The resulting document will look like this:</p>
 190  *
 191  * <pre>
 192  * &lt;?xml version="1.0" standalone="yes"?>
 193  *
 194  * &lt;foo:foo xmlns:foo="http://www.foo.com/ns/"/>
 195  * </pre>
 196  *
 197  * <p>The default Namespace simply uses an empty string as the prefix:</p>
 198  *
 199  * <pre>
 200  * w.setPrefix("http://www.foo.com/ns/", "");
 201  * w.startDocument();
 202  * w.emptyElement("http://www.foo.com/ns/", "foo");
 203  * w.endDocument();
 204  * </pre>
 205  *
 206  * <p>The resulting document will look like this:</p>
 207  *
 208  * <pre>
 209  * &lt;?xml version="1.0" standalone="yes"?>
 210  *
 211  * &lt;foo xmlns="http://www.foo.com/ns/"/>
 212  * </pre>
 213  *
 214  * <p>By default, the XML writer will not declare a Namespace until
 215  * it is actually used.  Sometimes, this approach will create
 216  * a large number of Namespace declarations, as in the following
 217  * example:</p>
 218  *
 219  * <pre>
 220  * &lt;xml version="1.0" standalone="yes"?>
 221  *
 222  * &lt;rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
 223  *  &lt;rdf:Description about="http://www.foo.com/ids/books/12345">
 224  *   &lt;dc:title xmlns:dc="http://www.purl.org/dc/">A Dark Night&lt;/dc:title>
 225  *   &lt;dc:creator xmlns:dc="http://www.purl.org/dc/">Jane Smith&lt;/dc:title>
 226  *   &lt;dc:date xmlns:dc="http://www.purl.org/dc/">2000-09-09&lt;/dc:title>
 227  *  &lt;/rdf:Description>
 228  * &lt;/rdf:RDF>
 229  * </pre>
 230  *
 231  * <p>The "rdf" prefix is declared only once, because the RDF Namespace
 232  * is used by the root element and can be inherited by all of its
 233  * descendants; the "dc" prefix, on the other hand, is declared three
 234  * times, because no higher element uses the Namespace.  To solve this
 235  * problem, you can instruct the XML writer to predeclare Namespaces
 236  * on the root element even if they are not used there:</p>
 237  *
 238  * <pre>
 239  * w.forceNSDecl("http://www.purl.org/dc/");
 240  * </pre>
 241  *
 242  * <p>Now, the "dc" prefix will be declared on the root element even
 243  * though it's not needed there, and can be inherited by its
 244  * descendants:</p>
 245  *
 246  * <pre>
 247  * &lt;xml version="1.0" standalone="yes"?>
 248  *
 249  * &lt;rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 250  *             xmlns:dc="http://www.purl.org/dc/">
 251  *  &lt;rdf:Description about="http://www.foo.com/ids/books/12345">
 252  *   &lt;dc:title>A Dark Night&lt;/dc:title>
 253  *   &lt;dc:creator>Jane Smith&lt;/dc:title>
 254  *   &lt;dc:date>2000-09-09&lt;/dc:title>
 255  *  &lt;/rdf:Description>
 256  * &lt;/rdf:RDF>
 257  * </pre>
 258  *
 259  * <p>This approach is also useful for declaring Namespace prefixes
 260  * that be used by qualified names appearing in attribute values or
 261  * character data.</p>
 262  *
 263  * @author David Megginson, david@megginson.com
 264  * @version 0.2
 265  * @since JAXB 1.0
 266  * @see org.xml.sax.XMLFilter
 267  * @see org.xml.sax.ContentHandler
 268  */
 269 public class XMLWriter extends XMLFilterImpl implements LexicalHandler
 270 {
 271     ////////////////////////////////////////////////////////////////////
 272     // Constructors.
 273     ////////////////////////////////////////////////////////////////////
 274 
 275 
 276 
 277 


 371      * @param writer The output destination, or null to use
 372      *        standard output.
 373      * @see #flush()
 374      */
 375     public void setOutput (Writer writer,String _encoding)
 376     {
 377         if (writer == null) {
 378             output = new OutputStreamWriter(System.out);
 379         } else {
 380             output = writer;
 381         }
 382         encoding = _encoding;
 383     }
 384 
 385     public void setEncoding(String encoding) {
 386         this.encoding = encoding;
 387     }
 388 
 389     /**
 390      * Set whether the writer should print out the XML declaration
 391      * (&lt;?xml version='1.0' ... ?>).
 392      * <p>
 393      * This option is set to true by default.
 394      */
 395     public void setXmlDecl( boolean _writeXmlDecl ) {
 396         this.writeXmlDecl = _writeXmlDecl;
 397     }
 398 
 399     /**
 400      * Sets the header string.
 401      *
 402      * This string will be written right after the xml declaration
 403      * without any escaping. Useful for generating a boiler-plate
 404      * DOCTYPE decl, PIs, and comments.
 405      *
 406      * @param _header
 407      *      passing null will work as if the empty string is passed.
 408      */
 409     public void setHeader( String _header ) {
 410         this.header = _header;
 411     }




  76  * <pre>
  77  * w.startElement("", "foo", "", new AttributesImpl());
  78  * </pre>
  79  *
  80  * <p>Except that it is more efficient because it does not allocate
  81  * a new empty attribute list each time.  The following code will send
  82  * a simple XML document to standard output:</p>
  83  *
  84  * <pre>
  85  * XMLWriter w = new XMLWriter();
  86  *
  87  * w.startDocument();
  88  * w.startElement("greeting");
  89  * w.characters("Hello, world!");
  90  * w.endElement("greeting");
  91  * w.endDocument();
  92  * </pre>
  93  *
  94  * <p>The resulting document will look like this:</p>
  95  *
  96  * <pre>{@code
  97  * <?xml version="1.0" standalone="yes"?>
  98  *
  99  * <greeting>Hello, world!</greeting>
 100  * }</pre>
 101  *
 102  * <p>In fact, there is an even simpler convenience method,
 103  * <var>dataElement</var>, designed for writing elements that
 104  * contain only character data, so the code to generate the
 105  * document could be shortened to</p>
 106  *
 107  * <pre>
 108  * XMLWriter w = new XMLWriter();
 109  *
 110  * w.startDocument();
 111  * w.dataElement("greeting", "Hello, world!");
 112  * w.endDocument();
 113  * </pre>
 114  *
 115  * <h2>Whitespace</h2>
 116  *
 117  * <p>According to the XML Recommendation, <em>all</em> whitespace
 118  * in an XML document is potentially significant to an application,
 119  * so this class never adds newlines or indentation.  If you
 120  * insert three elements in a row, as in</p>
 121  *
 122  * <pre>
 123  * w.dataElement("item", "1");
 124  * w.dataElement("item", "2");
 125  * w.dataElement("item", "3");
 126  * </pre>
 127  *
 128  * <p>you will end up with</p>
 129  *
 130  * <pre>{@code
 131  * <item>1</item><item>3</item><item>3</item>
 132  * }</pre>
 133  *
 134  * <p>You need to invoke one of the <var>characters</var> methods
 135  * explicitly to add newlines or indentation.  Alternatively, you
 136  * can use {@link DataWriter}, which
 137  * is derived from this class -- it is optimized for writing
 138  * purely data-oriented (or field-oriented) XML, and does automatic
 139  * linebreaks and indentation (but does not support mixed content
 140  * properly).</p>
 141  *
 142  *
 143  * <h2>Namespace Support</h2>
 144  *
 145  * <p>The writer contains extensive support for XML Namespaces, so that
 146  * a client application does not have to keep track of prefixes and
 147  * supply <var>xmlns</var> attributes.  By default, the XML writer will
 148  * generate Namespace declarations in the form _NS1, _NS2, etc., wherever
 149  * they are needed, as in the following example:</p>
 150  *
 151  * <pre>
 152  * w.startDocument();
 153  * w.emptyElement("http://www.foo.com/ns/", "foo");
 154  * w.endDocument();
 155  * </pre>
 156  *
 157  * <p>The resulting document will look like this:</p>
 158  *
 159  * <pre>{@code
 160  * <?xml version="1.0" standalone="yes"?>
 161  *
 162  * <_NS1:foo xmlns:_NS1="http://www.foo.com/ns/"/>
 163  * }</pre>
 164  *
 165  * <p>In many cases, document authors will prefer to choose their
 166  * own prefixes rather than using the (ugly) default names.  The
 167  * XML writer allows two methods for selecting prefixes:</p>
 168  *
 169  * <ol>
 170  * <li>the qualified name</li>
 171  * <li>the {@link #setPrefix setPrefix} method.</li>
 172  * </ol>
 173  *
 174  * <p>Whenever the XML writer finds a new Namespace URI, it checks
 175  * to see if a qualified (prefixed) name is also available; if so
 176  * it attempts to use the name's prefix (as long as the prefix is
 177  * not already in use for another Namespace URI).</p>
 178  *
 179  * <p>Before writing a document, the client can also pre-map a prefix
 180  * to a Namespace URI with the setPrefix method:</p>
 181  *
 182  * <pre>
 183  * w.setPrefix("http://www.foo.com/ns/", "foo");
 184  * w.startDocument();
 185  * w.emptyElement("http://www.foo.com/ns/", "foo");
 186  * w.endDocument();
 187  * </pre>
 188  *
 189  * <p>The resulting document will look like this:</p>
 190  *
 191  * <pre>{@code
 192  * <?xml version="1.0" standalone="yes"?>
 193  *
 194  * <foo:foo xmlns:foo="http://www.foo.com/ns/"/>
 195  * }</pre>
 196  *
 197  * <p>The default Namespace simply uses an empty string as the prefix:</p>
 198  *
 199  * <pre>
 200  * w.setPrefix("http://www.foo.com/ns/", "");
 201  * w.startDocument();
 202  * w.emptyElement("http://www.foo.com/ns/", "foo");
 203  * w.endDocument();
 204  * </pre>
 205  *
 206  * <p>The resulting document will look like this:</p>
 207  *
 208  * <pre>{@code
 209  * <?xml version="1.0" standalone="yes"?>
 210  *
 211  * <foo xmlns="http://www.foo.com/ns/"/>
 212  * }</pre>
 213  *
 214  * <p>By default, the XML writer will not declare a Namespace until
 215  * it is actually used.  Sometimes, this approach will create
 216  * a large number of Namespace declarations, as in the following
 217  * example:</p>
 218  *
 219  * <pre>{@code
 220  * <xml version="1.0" standalone="yes"?>
 221  *
 222  * <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
 223  *  <rdf:Description about="http://www.foo.com/ids/books/12345">
 224  *   <dc:title xmlns:dc="http://www.purl.org/dc/">A Dark Night</dc:title>
 225  *   <dc:creator xmlns:dc="http://www.purl.org/dc/">Jane Smith</dc:title>
 226  *   <dc:date xmlns:dc="http://www.purl.org/dc/">2000-09-09</dc:title>
 227  *  </rdf:Description>
 228  * </rdf:RDF>
 229  * }</pre>
 230  *
 231  * <p>The "rdf" prefix is declared only once, because the RDF Namespace
 232  * is used by the root element and can be inherited by all of its
 233  * descendants; the "dc" prefix, on the other hand, is declared three
 234  * times, because no higher element uses the Namespace.  To solve this
 235  * problem, you can instruct the XML writer to predeclare Namespaces
 236  * on the root element even if they are not used there:</p>
 237  *
 238  * <pre>
 239  * w.forceNSDecl("http://www.purl.org/dc/");
 240  * </pre>
 241  *
 242  * <p>Now, the "dc" prefix will be declared on the root element even
 243  * though it's not needed there, and can be inherited by its
 244  * descendants:</p>
 245  *
 246  * <pre>{@code
 247  * <xml version="1.0" standalone="yes"?>
 248  *
 249  * <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 250  *             xmlns:dc="http://www.purl.org/dc/">
 251  *  <rdf:Description about="http://www.foo.com/ids/books/12345">
 252  *   <dc:title>A Dark Night</dc:title>
 253  *   <dc:creator>Jane Smith</dc:title>
 254  *   <dc:date>2000-09-09</dc:title>
 255  *  </rdf:Description>
 256  * </rdf:RDF>
 257  * }</pre>
 258  *
 259  * <p>This approach is also useful for declaring Namespace prefixes
 260  * that be used by qualified names appearing in attribute values or
 261  * character data.</p>
 262  *
 263  * @author David Megginson, david@megginson.com
 264  * @version 0.2
 265  * @since JAXB 1.0
 266  * @see org.xml.sax.XMLFilter
 267  * @see org.xml.sax.ContentHandler
 268  */
 269 public class XMLWriter extends XMLFilterImpl implements LexicalHandler
 270 {
 271     ////////////////////////////////////////////////////////////////////
 272     // Constructors.
 273     ////////////////////////////////////////////////////////////////////
 274 
 275 
 276 
 277 


 371      * @param writer The output destination, or null to use
 372      *        standard output.
 373      * @see #flush()
 374      */
 375     public void setOutput (Writer writer,String _encoding)
 376     {
 377         if (writer == null) {
 378             output = new OutputStreamWriter(System.out);
 379         } else {
 380             output = writer;
 381         }
 382         encoding = _encoding;
 383     }
 384 
 385     public void setEncoding(String encoding) {
 386         this.encoding = encoding;
 387     }
 388 
 389     /**
 390      * Set whether the writer should print out the XML declaration
 391      * ({@code <?xml version='1.0' ... ?>}).
 392      * <p>
 393      * This option is set to true by default.
 394      */
 395     public void setXmlDecl( boolean _writeXmlDecl ) {
 396         this.writeXmlDecl = _writeXmlDecl;
 397     }
 398 
 399     /**
 400      * Sets the header string.
 401      *
 402      * This string will be written right after the xml declaration
 403      * without any escaping. Useful for generating a boiler-plate
 404      * DOCTYPE decl, PIs, and comments.
 405      *
 406      * @param _header
 407      *      passing null will work as if the empty string is passed.
 408      */
 409     public void setHeader( String _header ) {
 410         this.header = _header;
 411     }


< prev index next >