1
2
3
4
5
6
7
8 package org.dom4j;
9
10 import junit.textui.TestRunner;
11
12 import java.io.ByteArrayInputStream;
13 import java.io.ByteArrayOutputStream;
14 import java.io.StringReader;
15 import java.io.StringWriter;
16
17 import org.dom4j.io.OutputFormat;
18 import org.dom4j.io.SAXReader;
19 import org.dom4j.io.XMLWriter;
20 import org.dom4j.tree.BaseElement;
21 import org.dom4j.tree.DefaultDocument;
22
23 import org.xml.sax.ContentHandler;
24 import org.xml.sax.SAXException;
25 import org.xml.sax.helpers.AttributesImpl;
26
27 /***
28 * A simple test harness to check that the XML Writer works
29 *
30 * @author <a href="mailto:james.strachan@metastuff.com">James Strachan </a>
31 * @version $Revision: 1.7 $
32 */
33 public class XMLWriterTest extends AbstractTestCase {
34 protected static final boolean VERBOSE = false;
35
36 public static void main(String[] args) {
37 TestRunner.run(XMLWriterTest.class);
38 }
39
40
41
42 public void testBug1119733() throws Exception {
43 Document doc = DocumentHelper
44 .parseText("<root><code>foo</code> bar</root>");
45
46 StringWriter out = new StringWriter();
47 XMLWriter writer = new XMLWriter(out, OutputFormat.createPrettyPrint());
48 writer.write(doc);
49 writer.close();
50
51 String xml = out.toString();
52
53 System.out.println(xml);
54 assertEquals("whitespace problem", -1, xml.indexOf("</code>bar"));
55 }
56
57 public void testBug1119733WithSAXEvents() throws Exception {
58 StringWriter out = new StringWriter();
59 XMLWriter writer = new XMLWriter(out, OutputFormat.createPrettyPrint());
60 writer.startDocument();
61 writer.startElement(null, "root", "root", new AttributesImpl());
62 writer.startElement(null, "code", "code", new AttributesImpl());
63 writer.characters(new char[] {'f', 'o', 'o'}, 0, 3);
64 writer.endElement(null, "code", "code");
65 writer.characters(new char[] {' ', 'b', 'a', 'r'}, 0, 4);
66 writer.endElement(null, "root", "root");
67 writer.endDocument();
68 writer.close();
69
70 String xml = out.toString();
71
72 System.out.println(xml);
73 assertEquals("whitespace problem", -1, xml.indexOf("</code>bar"));
74 }
75
76
77
78 public void testWriter() throws Exception {
79 Object object = document;
80 StringWriter out = new StringWriter();
81
82 XMLWriter writer = new XMLWriter(out);
83 writer.write(object);
84 writer.close();
85
86 String text = out.toString();
87
88 if (VERBOSE) {
89 log("Text output is [");
90 log(text);
91 log("]. Done");
92 }
93
94 assertTrue("Output text is bigger than 10 characters",
95 text.length() > 10);
96 }
97
98 public void testEncodingFormats() throws Exception {
99 testEncoding("UTF-8");
100 testEncoding("UTF-16");
101 testEncoding("ISO-8859-1");
102 }
103
104 public void testWritingEmptyElement() throws Exception {
105 Document doc = DocumentFactory.getInstance().createDocument();
106 Element grandFather = doc.addElement("grandfather");
107 Element parent1 = grandFather.addElement("parent");
108 Element child1 = parent1.addElement("child1");
109 Element child2 = parent1.addElement("child2");
110 child2.setText("test");
111
112 Element parent2 = grandFather.addElement("parent");
113 Element child3 = parent2.addElement("child3");
114 child3.setText("test");
115
116 StringWriter buffer = new StringWriter();
117 OutputFormat format = OutputFormat.createPrettyPrint();
118 XMLWriter writer = new XMLWriter(buffer, format);
119 writer.write(doc);
120
121 String xml = buffer.toString();
122
123 System.out.println(xml);
124
125 assertTrue("child2 not present",
126 xml.indexOf("<child2>test</child2>") != -1);
127 }
128
129 protected void testEncoding(String encoding) throws Exception {
130 ByteArrayOutputStream out = new ByteArrayOutputStream();
131
132 OutputFormat format = OutputFormat.createPrettyPrint();
133 format.setEncoding(encoding);
134
135 XMLWriter writer = new XMLWriter(out, format);
136 writer.write(document);
137 writer.close();
138
139 log("Wrote to encoding: " + encoding);
140 }
141
142 public void testWriterBug() throws Exception {
143 Element project = new BaseElement("project");
144 Document doc = new DefaultDocument(project);
145
146 ByteArrayOutputStream out = new ByteArrayOutputStream();
147 XMLWriter writer = new XMLWriter(out, new OutputFormat("\t", true,
148 "ISO-8859-1"));
149 writer.write(doc);
150
151 ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
152 SAXReader reader = new SAXReader();
153 Document doc2 = reader.read(in);
154
155 assertTrue("Generated document has a root element", doc2
156 .getRootElement() != null);
157 assertEquals("Generated document has corrent named root element", doc2
158 .getRootElement().getName(), "project");
159 }
160
161 public void testNamespaceBug() throws Exception {
162 Document doc = DocumentHelper.createDocument();
163
164 Element root = doc.addElement("root", "ns1");
165 Element child1 = root.addElement("joe", "ns2");
166 child1.addElement("zot", "ns1");
167
168 StringWriter out = new StringWriter();
169 XMLWriter writer = new XMLWriter(out, OutputFormat.createPrettyPrint());
170 writer.write(doc);
171
172 String text = out.toString();
173
174
175 Document doc2 = DocumentHelper.parseText(text);
176 root = doc2.getRootElement();
177 assertEquals("root has incorrect namespace", "ns1", root
178 .getNamespaceURI());
179
180 Element joe = (Element) root.elementIterator().next();
181 assertEquals("joe has correct namespace", "ns2", joe.getNamespaceURI());
182
183 Element zot = (Element) joe.elementIterator().next();
184 assertEquals("zot has correct namespace", "ns1", zot.getNamespaceURI());
185 }
186
187 /***
188 * This test harness was supplied by Lari Hotari
189 *
190 * @throws Exception
191 * DOCUMENT ME!
192 */
193 public void testContentHandler() throws Exception {
194 StringWriter out = new StringWriter();
195 OutputFormat format = OutputFormat.createPrettyPrint();
196 format.setEncoding("iso-8859-1");
197
198 XMLWriter writer = new XMLWriter(out, format);
199 generateXML(writer);
200 writer.close();
201
202 String text = out.toString();
203
204 if (VERBOSE) {
205 log("Created XML");
206 log(text);
207 }
208
209
210 Document doc = DocumentHelper.parseText(text);
211 String value = doc.valueOf("/processes[@name='arvojoo']");
212 assertEquals("Document contains the correct text", "jeejee", value);
213 }
214
215 /***
216 * This test was provided by Manfred Lotz
217 *
218 * @throws Exception
219 * DOCUMENT ME!
220 */
221 public void testWhitespaceBug() throws Exception {
222 String notes = "<notes> This is a multiline\n\rentry</notes>";
223 Document doc = DocumentHelper.parseText(notes);
224
225 OutputFormat format = new OutputFormat();
226 format.setEncoding("UTF-8");
227 format.setIndentSize(4);
228 format.setNewlines(true);
229 format.setTrimText(true);
230 format.setExpandEmptyElements(true);
231
232 StringWriter buffer = new StringWriter();
233 XMLWriter writer = new XMLWriter(buffer, format);
234 writer.write(doc);
235
236 String xml = buffer.toString();
237 log(xml);
238
239 Document doc2 = DocumentHelper.parseText(xml);
240 String text = doc2.valueOf("/notes");
241 String expected = "This is a multiline entry";
242
243 assertEquals("valueOf() returns the correct text padding", expected,
244 text);
245
246 assertEquals("getText() returns the correct text padding", expected,
247 doc2.getRootElement().getText());
248 }
249
250 /***
251 * This test was provided by Manfred Lotz
252 *
253 * @throws Exception
254 * DOCUMENT ME!
255 */
256 public void testWhitespaceBug2() throws Exception {
257 Document doc = DocumentHelper.createDocument();
258 Element root = doc.addElement("root");
259 Element meaning = root.addElement("meaning");
260 meaning.addText("to li");
261 meaning.addText("ve");
262
263 OutputFormat format = new OutputFormat();
264 format.setEncoding("UTF-8");
265 format.setIndentSize(4);
266 format.setNewlines(true);
267 format.setTrimText(true);
268 format.setExpandEmptyElements(true);
269
270 StringWriter buffer = new StringWriter();
271 XMLWriter writer = new XMLWriter(buffer, format);
272 writer.write(doc);
273
274 String xml = buffer.toString();
275 log(xml);
276
277 Document doc2 = DocumentHelper.parseText(xml);
278 String text = doc2.valueOf("/root/meaning");
279 String expected = "to live";
280
281 assertEquals("valueOf() returns the correct text padding", expected,
282 text);
283
284 assertEquals("getText() returns the correct text padding", expected,
285 doc2.getRootElement().element("meaning").getText());
286 }
287
288 public void testPadding() throws Exception {
289 Document doc = DocumentFactory.getInstance().createDocument();
290 Element root = doc.addElement("root");
291 root.addText("prefix ");
292 root.addElement("b");
293 root.addText(" suffix");
294
295 OutputFormat format = new OutputFormat("", false);
296 format.setOmitEncoding(true);
297 format.setSuppressDeclaration(true);
298 format.setExpandEmptyElements(true);
299 format.setPadText(true);
300 format.setTrimText(true);
301
302 StringWriter buffer = new StringWriter();
303 XMLWriter writer = new XMLWriter(buffer, format);
304 writer.write(doc);
305
306 String xml = buffer.toString();
307
308 System.out.println("xml: " + xml);
309
310 String expected = "<root>prefix <b></b> suffix</root>";
311 assertEquals(expected, xml);
312 }
313
314 public void testPadding2() throws Exception {
315 Document doc = DocumentFactory.getInstance().createDocument();
316 Element root = doc.addElement("root");
317 root.addText("prefix");
318 root.addElement("b");
319 root.addText("suffix");
320
321 OutputFormat format = new OutputFormat("", false);
322 format.setOmitEncoding(true);
323 format.setSuppressDeclaration(true);
324 format.setExpandEmptyElements(true);
325 format.setPadText(true);
326 format.setTrimText(true);
327
328 StringWriter buffer = new StringWriter();
329 XMLWriter writer = new XMLWriter(buffer, format);
330 writer.write(doc);
331
332 String xml = buffer.toString();
333
334 System.out.println("xml: " + xml);
335
336 String expected = "<root>prefix<b></b>suffix</root>";
337 assertEquals(expected, xml);
338 }
339
340
341
342
343 public void testPrettyPrinting() throws Exception {
344 Document doc = DocumentFactory.getInstance().createDocument();
345 doc.addElement("summary").addAttribute("date", "6/7/8").addElement(
346 "orderline").addText("puffins").addElement("ranjit")
347 .addComment("Ranjit is a happy Puffin");
348
349 XMLWriter writer = new XMLWriter(System.out, OutputFormat
350 .createPrettyPrint());
351 writer.write(doc);
352
353 doc = DocumentFactory.getInstance().createDocument();
354 doc.addElement("summary").addAttribute("date", "6/7/8").addElement(
355 "orderline").addText("puffins").addElement("ranjit")
356 .addComment("Ranjit is a happy Puffin").addComment(
357 "another comment").addElement("anotherElement");
358 writer.write(doc);
359 }
360
361 public void testAttributeQuotes() throws Exception {
362 Document doc = DocumentFactory.getInstance().createDocument();
363 doc.addElement("root").addAttribute("test", "text with ' in it");
364
365 StringWriter out = new StringWriter();
366 XMLWriter writer = new XMLWriter(out, OutputFormat
367 .createCompactFormat());
368 writer.write(doc);
369
370 String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
371 + "<root test=\"text with ' in it\"/>";
372 assertEquals(expected, out.toString());
373 }
374
375 public void testBug868408() throws Exception {
376 Document doc = getDocument("/xml/web.xml");
377 Document doc2 = DocumentHelper.parseText(doc.asXML());
378 assertEquals(doc.asXML(), doc2.asXML());
379 }
380
381 public void testBug923882() throws Exception {
382 Document doc = DocumentFactory.getInstance().createDocument();
383 Element root = doc.addElement("root");
384 root.addText("this is ");
385 root.addText(" sim");
386 root.addText("ple text ");
387 root.addElement("child");
388 root.addText(" contai");
389 root.addText("ning spaces and");
390 root.addText(" multiple textnodes");
391
392 OutputFormat format = new OutputFormat();
393 format.setEncoding("UTF-8");
394 format.setIndentSize(4);
395 format.setNewlines(true);
396 format.setTrimText(true);
397 format.setExpandEmptyElements(true);
398
399 StringWriter buffer = new StringWriter();
400 XMLWriter writer = new XMLWriter(buffer, format);
401 writer.write(doc);
402
403 String xml = buffer.toString();
404 log(xml);
405
406 int start = xml.indexOf("<root");
407 int end = xml.indexOf("/root>") + 6;
408 String eol = "\n";
409 String expected = "<root>this is simple text" + eol
410 + " <child></child>containing spaces and multiple textnodes"
411 + eol + "</root>";
412 System.out.println("Expected:");
413 System.out.println(expected);
414 System.out.println("Obtained:");
415 System.out.println(xml.substring(start, end));
416 assertEquals(expected, xml.substring(start, end));
417 }
418
419 public void testEscapeXML() throws Exception {
420 ByteArrayOutputStream os = new ByteArrayOutputStream();
421 OutputFormat format = new OutputFormat(null, false, "ISO-8859-2");
422 format.setSuppressDeclaration(true);
423
424 XMLWriter writer = new XMLWriter(os, format);
425
426 Document document = DocumentFactory.getInstance().createDocument();
427 Element root = document.addElement("root");
428 root.setText("bla &#c bla");
429
430 writer.write(document);
431
432 String result = os.toString();
433 System.out.println(result);
434
435 Document doc2 = DocumentHelper.parseText(result);
436 doc2.normalize();
437 System.out.println(doc2.getRootElement().getText());
438 assertNodesEqual(document, doc2);
439 }
440
441 public void testWriteEntities() throws Exception {
442 String xml = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"
443 + "<!DOCTYPE xml [<!ENTITY copy \"©\"> "
444 + "<!ENTITY trade \"™\"> "
445 + "<!ENTITY deg \"°\"> " + "<!ENTITY gt \">\"> "
446 + "<!ENTITY sup2 \"²\"> "
447 + "<!ENTITY frac14 \"¼\"> "
448 + "<!ENTITY quot \""\"> "
449 + "<!ENTITY frac12 \"½\"> "
450 + "<!ENTITY euro \"€\"> "
451 + "<!ENTITY Omega \"Ω\"> ]>\n" + "<root />";
452
453 SAXReader reader = new SAXReader("org.apache.xerces.parsers.SAXParser");
454 reader.setIncludeInternalDTDDeclarations(true);
455
456 Document doc = reader.read(new StringReader(xml));
457 StringWriter wr = new StringWriter();
458 XMLWriter writer = new XMLWriter(wr);
459 writer.write(doc);
460
461 String xml2 = wr.toString();
462 System.out.println(xml2);
463
464 Document doc2 = DocumentHelper.parseText(xml2);
465
466 assertNodesEqual(doc, doc2);
467 }
468
469 public void testEscapeChars() throws Exception {
470 Document document = DocumentFactory.getInstance().createDocument();
471 Element root = document.addElement("root");
472 root.setText("blahblah " + '\u008f');
473
474 XMLWriter writer = new XMLWriter();
475 StringWriter strWriter = new StringWriter();
476 writer.setWriter(strWriter);
477 writer.setMaximumAllowedCharacter(127);
478 writer.write(document);
479
480 String xml = strWriter.toString();
481 }
482
483 public void testEscapeText() throws SAXException {
484 StringWriter writer = new StringWriter();
485 XMLWriter xmlWriter = new XMLWriter(writer);
486 xmlWriter.setEscapeText(false);
487
488 String txt = "<test></test>";
489
490 xmlWriter.startDocument();
491 xmlWriter.characters(txt.toCharArray(), 0, txt.length());
492 xmlWriter.endDocument();
493
494 String output = writer.toString();
495 System.out.println(output);
496 assertTrue(output.indexOf("<test>") != -1);
497 }
498
499 public void testNullCData() {
500 Element e = DocumentHelper.createElement("test");
501 e.add(DocumentHelper.createElement("another").addCDATA(null));
502
503 Document doc = DocumentHelper.createDocument(e);
504
505 assertEquals(-1, e.asXML().indexOf("null"));
506 assertEquals(-1, doc.asXML().indexOf("null"));
507
508 System.out.println(e.asXML());
509 System.out.println(doc.asXML());
510 }
511
512 protected void generateXML(ContentHandler handler) throws SAXException {
513 handler.startDocument();
514
515 AttributesImpl attrs = new AttributesImpl();
516 attrs.clear();
517 attrs.addAttribute("", "", "name", "CDATA", "arvojoo");
518 handler.startElement("", "", "processes", attrs);
519
520 String text = "jeejee";
521 char[] textch = text.toCharArray();
522 handler.characters(textch, 0, textch.length);
523 handler.endElement("", "", "processes");
524 handler.endDocument();
525 }
526 }
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563