1 /*
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
74 * <pre>
75 * w.startElement("", "foo", "", new AttributesImpl());
76 * </pre>
77 *
78 * <p>Except that it is more efficient because it does not allocate
79 * a new empty attribute list each time. The following code will send
80 * a simple XML document to standard output:</p>
81 *
82 * <pre>
83 * XMLWriter w = new XMLWriter();
84 *
85 * w.startDocument();
86 * w.startElement("greeting");
87 * w.characters("Hello, world!");
88 * w.endElement("greeting");
89 * w.endDocument();
90 * </pre>
91 *
92 * <p>The resulting document will look like this:</p>
93 *
94 * <pre>
95 * <?xml version="1.0" standalone="yes"?>
96 *
97 * <greeting>Hello, world!</greeting>
98 * </pre>
99 *
100 * <p>In fact, there is an even simpler convenience method,
101 * <var>dataElement</var>, designed for writing elements that
102 * contain only character data, so the code to generate the
103 * document could be shortened to</p>
104 *
105 * <pre>
106 * XMLWriter w = new XMLWriter();
107 *
108 * w.startDocument();
109 * w.dataElement("greeting", "Hello, world!");
110 * w.endDocument();
111 * </pre>
112 *
113 * <h2>Whitespace</h2>
114 *
115 * <p>According to the XML Recommendation, <em>all</em> whitespace
116 * in an XML document is potentially significant to an application,
117 * so this class never adds newlines or indentation. If you
118 * insert three elements in a row, as in</p>
119 *
120 * <pre>
121 * w.dataElement("item", "1");
122 * w.dataElement("item", "2");
123 * w.dataElement("item", "3");
124 * </pre>
125 *
126 * <p>you will end up with</p>
127 *
128 * <pre>
129 * <item>1</item><item>3</item><item>3</item>
130 * </pre>
131 *
132 * <p>You need to invoke one of the <var>characters</var> methods
133 * explicitly to add newlines or indentation. Alternatively, you
134 * can use {@link DataWriter}, which
135 * is derived from this class -- it is optimized for writing
136 * purely data-oriented (or field-oriented) XML, and does automatic
137 * linebreaks and indentation (but does not support mixed content
138 * properly).</p>
139 *
140 *
141 * <h2>Namespace Support</h2>
142 *
143 * <p>The writer contains extensive support for XML Namespaces, so that
144 * a client application does not have to keep track of prefixes and
145 * supply <var>xmlns</var> attributes. By default, the XML writer will
146 * generate Namespace declarations in the form _NS1, _NS2, etc., wherever
147 * they are needed, as in the following example:</p>
148 *
149 * <pre>
150 * w.startDocument();
151 * w.emptyElement("http://www.foo.com/ns/", "foo");
152 * w.endDocument();
153 * </pre>
154 *
155 * <p>The resulting document will look like this:</p>
156 *
157 * <pre>
158 * <?xml version="1.0" standalone="yes"?>
159 *
160 * <_NS1:foo xmlns:_NS1="http://www.foo.com/ns/"/>
161 * </pre>
162 *
163 * <p>In many cases, document authors will prefer to choose their
164 * own prefixes rather than using the (ugly) default names. The
165 * XML writer allows two methods for selecting prefixes:</p>
166 *
167 * <ol>
168 * <li>the qualified name</li>
169 * </ol>
170 *
171 * <p>Whenever the XML writer finds a new Namespace URI, it checks
172 * to see if a qualified (prefixed) name is also available; if so
173 * it attempts to use the name's prefix (as long as the prefix is
174 * not already in use for another Namespace URI).</p>
175 *
176 * <p>The resulting document will look like this:</p>
177 *
178 * <pre>
179 * <?xml version="1.0" standalone="yes"?>
180 *
181 * <foo:foo xmlns:foo="http://www.foo.com/ns/"/>
182 * </pre>
183 *
184 * <p>The default Namespace simply uses an empty string as the prefix:</p>
185 *
186 * <pre>
187 * w.setPrefix("http://www.foo.com/ns/", "");
188 * w.startDocument();
189 * w.emptyElement("http://www.foo.com/ns/", "foo");
190 * w.endDocument();
191 * </pre>
192 *
193 * <p>The resulting document will look like this:</p>
194 *
195 * <pre>
196 * <?xml version="1.0" standalone="yes"?>
197 *
198 * <foo xmlns="http://www.foo.com/ns/"/>
199 * </pre>
200 *
201 * <p>By default, the XML writer will not declare a Namespace until
202 * it is actually used. Sometimes, this approach will create
203 * a large number of Namespace declarations, as in the following
204 * example:</p>
205 *
206 * <pre>
207 * <xml version="1.0" standalone="yes"?>
208 *
209 * <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
210 * <rdf:Description about="http://www.foo.com/ids/books/12345">
211 * <dc:title xmlns:dc="http://www.purl.org/dc/">A Dark Night</dc:title>
212 * <dc:creator xmlns:dc="http://www.purl.org/dc/">Jane Smith</dc:title>
213 * <dc:date xmlns:dc="http://www.purl.org/dc/">2000-09-09</dc:title>
214 * </rdf:Description>
215 * </rdf:RDF>
216 * </pre>
217 *
218 * <p>The "rdf" prefix is declared only once, because the RDF Namespace
219 * is used by the root element and can be inherited by all of its
220 * descendants; the "dc" prefix, on the other hand, is declared three
221 * times, because no higher element uses the Namespace. To solve this
222 * problem, you can instruct the XML writer to predeclare Namespaces
223 * on the root element even if they are not used there:</p>
224 *
225 * <pre>
226 * w.forceNSDecl("http://www.purl.org/dc/");
227 * </pre>
228 *
229 * <p>Now, the "dc" prefix will be declared on the root element even
230 * though it's not needed there, and can be inherited by its
231 * descendants:</p>
232 *
233 * <pre>
234 * <xml version="1.0" standalone="yes"?>
235 *
236 * <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
237 * xmlns:dc="http://www.purl.org/dc/">
238 * <rdf:Description about="http://www.foo.com/ids/books/12345">
239 * <dc:title>A Dark Night</dc:title>
240 * <dc:creator>Jane Smith</dc:title>
241 * <dc:date>2000-09-09</dc:title>
242 * </rdf:Description>
243 * </rdf:RDF>
244 * </pre>
245 *
246 * <p>This approach is also useful for declaring Namespace prefixes
247 * that be used by qualified names appearing in attribute values or
248 * character data.</p>
249 *
250 * @author David Megginson, david@megginson.com
251 * @version 0.2
252 * @since JAXB 1.0
253 * @see org.xml.sax.XMLFilter
254 * @see org.xml.sax.ContentHandler
255 */
256 public class XMLWriter extends XMLFilterImpl
257 {
258
259 ////////////////////////////////////////////////////////////////////
260 // Constructors.
261 ////////////////////////////////////////////////////////////////////
262
263
264
355
356 /**
357 * Set a new output destination for the document.
358 *
359 * @param writer The output destination, or null to use
360 * standard output.
361 * @see #flush()
362 */
363 public void setOutput (Writer writer,String _encoding)
364 {
365 if (writer == null) {
366 output = new OutputStreamWriter(System.out);
367 } else {
368 output = writer;
369 }
370 encoding = _encoding;
371 }
372
373 /**
374 * Set whether the writer should print out the XML declaration
375 * (<?xml version='1.0' ... ?>).
376 * <p>
377 * This option is set to true by default.
378 */
379 public void setXmlDecl( boolean _writeXmlDecl ) {
380 this.writeXmlDecl = _writeXmlDecl;
381 }
382
383 /**
384 * Sets the header string.
385 *
386 * This string will be written right after the xml declaration
387 * without any escaping. Useful for generating a boiler-plate
388 * DOCTYPE decl, PIs, and comments.
389 *
390 * @param _header
391 * passing null will work as if the empty string is passed.
392 */
393 public void setHeader( String _header ) {
394 this.header = _header;
395 }
|
1 /*
2 * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
74 * <pre>
75 * w.startElement("", "foo", "", new AttributesImpl());
76 * </pre>
77 *
78 * <p>Except that it is more efficient because it does not allocate
79 * a new empty attribute list each time. The following code will send
80 * a simple XML document to standard output:</p>
81 *
82 * <pre>
83 * XMLWriter w = new XMLWriter();
84 *
85 * w.startDocument();
86 * w.startElement("greeting");
87 * w.characters("Hello, world!");
88 * w.endElement("greeting");
89 * w.endDocument();
90 * </pre>
91 *
92 * <p>The resulting document will look like this:</p>
93 *
94 * <pre>{@code
95 * <?xml version="1.0" standalone="yes"?>
96 *
97 * <greeting>Hello, world!</greeting>
98 * }</pre>
99 *
100 * <p>In fact, there is an even simpler convenience method,
101 * <var>dataElement</var>, designed for writing elements that
102 * contain only character data, so the code to generate the
103 * document could be shortened to</p>
104 *
105 * <pre>
106 * XMLWriter w = new XMLWriter();
107 *
108 * w.startDocument();
109 * w.dataElement("greeting", "Hello, world!");
110 * w.endDocument();
111 * </pre>
112 *
113 * <h2>Whitespace</h2>
114 *
115 * <p>According to the XML Recommendation, <em>all</em> whitespace
116 * in an XML document is potentially significant to an application,
117 * so this class never adds newlines or indentation. If you
118 * insert three elements in a row, as in</p>
119 *
120 * <pre>
121 * w.dataElement("item", "1");
122 * w.dataElement("item", "2");
123 * w.dataElement("item", "3");
124 * </pre>
125 *
126 * <p>you will end up with</p>
127 *
128 * <pre>{@code
129 * <item>1</item><item>3</item><item>3</item>
130 * }</pre>
131 *
132 * <p>You need to invoke one of the <var>characters</var> methods
133 * explicitly to add newlines or indentation. Alternatively, you
134 * can use {@link DataWriter}, which
135 * is derived from this class -- it is optimized for writing
136 * purely data-oriented (or field-oriented) XML, and does automatic
137 * linebreaks and indentation (but does not support mixed content
138 * properly).</p>
139 *
140 *
141 * <h2>Namespace Support</h2>
142 *
143 * <p>The writer contains extensive support for XML Namespaces, so that
144 * a client application does not have to keep track of prefixes and
145 * supply <var>xmlns</var> attributes. By default, the XML writer will
146 * generate Namespace declarations in the form _NS1, _NS2, etc., wherever
147 * they are needed, as in the following example:</p>
148 *
149 * <pre>
150 * w.startDocument();
151 * w.emptyElement("http://www.foo.com/ns/", "foo");
152 * w.endDocument();
153 * </pre>
154 *
155 * <p>The resulting document will look like this:</p>
156 *
157 * <pre>{@code
158 * <?xml version="1.0" standalone="yes"?>
159 *
160 * <_NS1:foo xmlns:_NS1="http://www.foo.com/ns/"/>
161 * }</pre>
162 *
163 * <p>In many cases, document authors will prefer to choose their
164 * own prefixes rather than using the (ugly) default names. The
165 * XML writer allows two methods for selecting prefixes:</p>
166 *
167 * <ol>
168 * <li>the qualified name</li>
169 * </ol>
170 *
171 * <p>Whenever the XML writer finds a new Namespace URI, it checks
172 * to see if a qualified (prefixed) name is also available; if so
173 * it attempts to use the name's prefix (as long as the prefix is
174 * not already in use for another Namespace URI).</p>
175 *
176 * <p>The resulting document will look like this:</p>
177 *
178 * <pre>{@code
179 * <?xml version="1.0" standalone="yes"?>
180 *
181 * <foo:foo xmlns:foo="http://www.foo.com/ns/"/>
182 * }</pre>
183 *
184 * <p>The default Namespace simply uses an empty string as the prefix:</p>
185 *
186 * <pre>
187 * w.setPrefix("http://www.foo.com/ns/", "");
188 * w.startDocument();
189 * w.emptyElement("http://www.foo.com/ns/", "foo");
190 * w.endDocument();
191 * </pre>
192 *
193 * <p>The resulting document will look like this:</p>
194 *
195 * <pre>{@code
196 * <?xml version="1.0" standalone="yes"?>
197 *
198 * <foo xmlns="http://www.foo.com/ns/"/>
199 * }</pre>
200 *
201 * <p>By default, the XML writer will not declare a Namespace until
202 * it is actually used. Sometimes, this approach will create
203 * a large number of Namespace declarations, as in the following
204 * example:</p>
205 *
206 * <pre>{@code
207 * <xml version="1.0" standalone="yes"?>
208 *
209 * <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
210 * <rdf:Description about="http://www.foo.com/ids/books/12345">
211 * <dc:title xmlns:dc="http://www.purl.org/dc/">A Dark Night</dc:title>
212 * <dc:creator xmlns:dc="http://www.purl.org/dc/">Jane Smith</dc:title>
213 * <dc:date xmlns:dc="http://www.purl.org/dc/">2000-09-09</dc:title>
214 * </rdf:Description>
215 * </rdf:RDF>
216 * }</pre>
217 *
218 * <p>The "rdf" prefix is declared only once, because the RDF Namespace
219 * is used by the root element and can be inherited by all of its
220 * descendants; the "dc" prefix, on the other hand, is declared three
221 * times, because no higher element uses the Namespace. To solve this
222 * problem, you can instruct the XML writer to predeclare Namespaces
223 * on the root element even if they are not used there:</p>
224 *
225 * <pre>
226 * w.forceNSDecl("http://www.purl.org/dc/");
227 * </pre>
228 *
229 * <p>Now, the "dc" prefix will be declared on the root element even
230 * though it's not needed there, and can be inherited by its
231 * descendants:</p>
232 *
233 * <pre>{@code
234 * <xml version="1.0" standalone="yes"?>
235 *
236 * <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
237 * xmlns:dc="http://www.purl.org/dc/">
238 * <rdf:Description about="http://www.foo.com/ids/books/12345">
239 * <dc:title>A Dark Night</dc:title>
240 * <dc:creator>Jane Smith</dc:title>
241 * <dc:date>2000-09-09</dc:title>
242 * </rdf:Description>
243 * </rdf:RDF>
244 * }</pre>
245 *
246 * <p>This approach is also useful for declaring Namespace prefixes
247 * that be used by qualified names appearing in attribute values or
248 * character data.</p>
249 *
250 * @author David Megginson, david@megginson.com
251 * @version 0.2
252 * @since JAXB 1.0
253 * @see org.xml.sax.XMLFilter
254 * @see org.xml.sax.ContentHandler
255 */
256 public class XMLWriter extends XMLFilterImpl
257 {
258
259 ////////////////////////////////////////////////////////////////////
260 // Constructors.
261 ////////////////////////////////////////////////////////////////////
262
263
264
355
356 /**
357 * Set a new output destination for the document.
358 *
359 * @param writer The output destination, or null to use
360 * standard output.
361 * @see #flush()
362 */
363 public void setOutput (Writer writer,String _encoding)
364 {
365 if (writer == null) {
366 output = new OutputStreamWriter(System.out);
367 } else {
368 output = writer;
369 }
370 encoding = _encoding;
371 }
372
373 /**
374 * Set whether the writer should print out the XML declaration
375 * ({@code <?xml version='1.0' ... ?>}).
376 * <p>
377 * This option is set to true by default.
378 */
379 public void setXmlDecl( boolean _writeXmlDecl ) {
380 this.writeXmlDecl = _writeXmlDecl;
381 }
382
383 /**
384 * Sets the header string.
385 *
386 * This string will be written right after the xml declaration
387 * without any escaping. Useful for generating a boiler-plate
388 * DOCTYPE decl, PIs, and comments.
389 *
390 * @param _header
391 * passing null will work as if the empty string is passed.
392 */
393 public void setHeader( String _header ) {
394 this.header = _header;
395 }
|