1 /*
   2  * Copyright (c) 2014, 2016, 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.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 package common;
  25 
  26 import static org.testng.Assert.assertEquals;
  27 
  28 import java.io.IOException;
  29 import java.io.StringReader;
  30 import java.io.StringWriter;
  31 
  32 import javax.xml.parsers.DocumentBuilder;
  33 import javax.xml.parsers.DocumentBuilderFactory;
  34 import javax.xml.parsers.ParserConfigurationException;
  35 import javax.xml.transform.OutputKeys;
  36 import javax.xml.transform.Transformer;
  37 import javax.xml.transform.TransformerFactory;
  38 import javax.xml.transform.dom.DOMSource;
  39 import javax.xml.transform.stream.StreamResult;
  40 import javax.xml.transform.stream.StreamSource;
  41 
  42 import org.testng.Assert;
  43 import org.testng.annotations.DataProvider;
  44 import org.testng.annotations.Listeners;
  45 import org.testng.annotations.Test;
  46 import org.w3c.dom.DOMConfiguration;
  47 import org.w3c.dom.DOMImplementation;
  48 import org.w3c.dom.Document;
  49 import org.w3c.dom.Node;
  50 import org.w3c.dom.Text;
  51 import org.w3c.dom.bootstrap.DOMImplementationRegistry;
  52 import org.w3c.dom.ls.DOMImplementationLS;
  53 import org.w3c.dom.ls.LSOutput;
  54 import org.w3c.dom.ls.LSSerializer;
  55 import org.xml.sax.InputSource;
  56 import org.xml.sax.SAXException;
  57 
  58 
  59 /*
  60  * @test
  61  * @bug 6439439 8087303
  62  * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
  63  * @run testng/othervm -DrunSecMngr=true common.PrettyPrintTest
  64  * @run testng/othervm common.PrettyPrintTest
  65  * @summary Test serializing xml and html with indentation.
  66  */
  67 @Listeners({jaxp.library.BasePolicy.class})
  68 public class PrettyPrintTest {
  69     /*
  70      * test pure text content, CDATA, elements only, text and element,
  71      * whitespace and element, xml:space property and nested xml:space property,
  72      * mixed node types, sequent Text nodes.
  73      */
  74     @DataProvider(name = "xml-data")
  75     public Object[][] xmlData() throws Exception {
  76         return new Object[][] {
  77                 { newTextNode("  abc def \nline2 &a \n test"),
  78                         "  abc def \n" +
  79                         "line2 &a \n" +
  80                         " test" },
  81                 { toXmlDocument("<a><![CDATA[ ]]></a>"),
  82                         "<a>\n" +
  83                         "    <![CDATA[ ]]>\n" +
  84                         "</a>\n" },
  85                 { toXmlDocument("<a><![CDATA[  abc def \nline2 &a \n test]]></a>"),
  86                         "<a>\n" +
  87                         "    <![CDATA[  abc def \n" +
  88                         "line2 &a \n" +
  89                         " test]]>\n" +
  90                         "</a>\n" },
  91                 { toXmlDocument("<rss version=\"2.0\"><ns:test id='i001'><ns:child></ns:child></ns:test></rss>"),
  92                         "<rss version=\"2.0\">\n" +
  93                         "    <ns:test id=\"i001\">\n" +
  94                         "        <ns:child/>\n" +
  95                         "    </ns:test>\n" +
  96                         "</rss>\n" },
  97                 { toXmlDocument("<rss version=\"2.0\"><ns:test id='i001'><ns:child>child1</ns:child>"
  98                         + "<test att1='v1'>  abc test</test></ns:test></rss>"),
  99                         "<rss version=\"2.0\">\n" +
 100                         "    <ns:test id=\"i001\">\n" +
 101                         "        <ns:child>child1</ns:child>\n" +
 102                         "        <test att1=\"v1\">  abc test</test>\n" +
 103                         "    </ns:test>\n" +
 104                         "</rss>\n" },
 105                 { toXmlDocument("<rss version=\"2.0\"><channel> <title>Java Tutorials and Examples 1</title> "
 106                         + "<language>en-us</language></channel><a><b> </b></a> <c>\n \n</c></rss>"),
 107                         "<rss version=\"2.0\">\n" +
 108                         "    <channel>\n" +
 109                         "        <title>Java Tutorials and Examples 1</title>\n" +
 110                         "        <language>en-us</language>\n" +
 111                         "    </channel>\n" +
 112                         "    <a>\n" +
 113                         "        <b/>\n" +
 114                         "    </a>\n" +
 115                         "    <c/>\n" +
 116                         "</rss>\n" },
 117                 { toXmlDocument("<rss version=\"2.0\"><channel xml:space=\"preserve\"> "
 118                         + "<title>Java Tutorials and Examples 1</title> <language>en-us</language></channel></rss>"),
 119                         "<rss version=\"2.0\">\n" +
 120                         "    <channel xml:space=\"preserve\"> <title>Java Tutorials and Examples 1</title> <language>en-us</language></channel>\n" +
 121                         "</rss>\n" },
 122                 { toXmlDocument("<rss><layer1 xml:space=\"preserve\"> <title>Java </title> "
 123                         + "<layer2 xml:space=\"asfsa\"> <layer3> "
 124                         + "<layer4 xml:space=\"default\"> <l5>5</l5> \n </layer4>"
 125                         + " </layer3> </layer2> "
 126                         + "<layer2 xml:space=\"default\"> "
 127                         + "<layer3> <l4> </l4> </layer3> "
 128                         + "<layer3 xml:space=\"preserve\"> <l4> </l4> </layer3>"
 129                         + "</layer2> </layer1></rss>"),
 130                         "<rss>\n" +
 131                         "    <layer1 xml:space=\"preserve\"> <title>Java </title> <layer2 xml:space=\"asfsa\"> <layer3> <layer4 xml:space=\"default\">\n" +
 132                         "                    <l5>5</l5>\n" +
 133                         "                </layer4> </layer3> </layer2> <layer2 xml:space=\"default\">\n" +
 134                         "            <layer3>\n" +
 135                         "                <l4/>\n" +
 136                         "            </layer3>\n" +
 137                         "            <layer3 xml:space=\"preserve\"> <l4> </l4> </layer3>\n" +
 138                         "        </layer2> </layer1>\n" +
 139                         "</rss>\n" },
 140                 { toXmlDocument(MIXED_NODE_TYPES_XML),
 141                         "<root>\n" +
 142                         "    \n" +
 143                         "     t\n" +
 144                         "    <![CDATA[ ]]>\n" +
 145                         "    \n" +
 146                         "t   \n" +
 147                         "    \n" +
 148                         "    <child1/>\n" +
 149                         "    \n" +
 150                         "    t\n" +
 151                         "    <!-- test comment -->\n" +
 152                         "    <child2/>\n" +
 153                         "    <child5>\n" +
 154                         "        \n" +
 155                         "        t\n" +
 156                         "        <?target1 test?>\n" +
 157                         "        <child51>\n" +
 158                         "            <child511>t</child511>\n" +
 159                         "        </child51>\n" +
 160                         "        <?target1 test?>\n" +
 161                         "        \n" +
 162                         "        t\n" +
 163                         "    \n" +
 164                         "    </child5>\n" +
 165                         "</root>\n" },
 166                 { createDocWithSequentTextNodes(),
 167                         "<root>\n" +
 168                         "     t\n" +
 169                         "t   \n" +
 170                         "    <child1/>\n" +
 171                         "    t\n" +
 172                         "    <child2/>\n" +
 173                         "    <child3/>\n" +
 174                         "    <child4/>\n" +
 175                         "    <child5>\n" +
 176                         "        t\n" +
 177                         "        <child51>\n" +
 178                         "            <child511>t</child511>\n" +
 179                         "        </child51>\n" +
 180                         "        t\n" +
 181                         "    </child5>\n" +
 182                         "    <!-- test comment -->\n" +
 183                         "    <!-- -->\n" +
 184                         "    <?target1 test?>\n" +
 185                         "</root>\n" } };
 186     }
 187 
 188     /*
 189      * @bug 8087303
 190      * Test the whitespace text nodes are serialized with pretty-print by LSSerializer and transformer correctly
 191      *
 192      */
 193     @Test(dataProvider = "xml-data")
 194     public void testXMLPrettyPrint(Node xml, String expected) throws Exception {
 195         assertEquals(serializerWrite(xml), expected);
 196         assertEquals(transform(xml).replaceAll("\r\n", "\n"), expected);
 197     }
 198 
 199     /*
 200      * test block element, inline element, text, and mixed elements.
 201      */
 202     @DataProvider(name = "html-data")
 203     public Object[][] htmlData() throws Exception {
 204         return new Object[][] {
 205                 { "<rss version=\"2.0\"><channel xml:space=\"preserve\"><title>Java Tutorials and Examples 1" +
 206                         "</title> <language>en-us</language></channel></rss>",
 207                         "<rss version=\"2.0\">\n" + 
 208                         "    <channel xml:space=\"preserve\">\n" + 
 209                         "        <title>Java Tutorials and Examples 1</title>\n" + 
 210                         "        <language>en-us</language>\n" + 
 211                         "    </channel>\n" + 
 212                         "</rss>\n" },
 213                 { "<html><code>Java</code><b><sup>TM</sup></b></html>",
 214                         "<html>\n" + 
 215                         "    <code>Java</code><b><sup>TM</sup></b>\n" + 
 216                         "</html>\n" },
 217                 { "<p>this is <a href=\"test.html\">a <strong>test</strong></a> page</p>",
 218                         "<p>\n" + 
 219                         "    this is <a href=\"test.html\">a <strong>test</strong></a> page\n" + 
 220                         "</p>\n" },
 221                 { "<html><body><h1>A heading</h1><p>new paragraph<form>an empty form</form>" +
 222                         "<a href=\"test.html\">test</a></p></body></html>",
 223                         "<html>\n" + 
 224                         "    <body>\n" + 
 225                         "        <h1>A heading</h1>\n" + 
 226                         "        <p>\n" + 
 227                         "            new paragraph\n" + 
 228                         "            <form>an empty form</form>\n" + 
 229                         "            <a href=\"test.html\">test</a>\n" + 
 230                         "        </p>\n" + 
 231                         "    </body>\n" + 
 232                         "</html>\n" },
 233                 { "<html><p>this is a mixed test <a href=\"test.html\">click<p>to the test" +
 234                         "</p>page</a>link end</p></html>",
 235                         "<html>\n" + 
 236                         "    <p>\n" + 
 237                         "        this is a mixed test <a href=\"test.html\">click\n" + 
 238                         "            <p>to the test</p>\n" + 
 239                         "            page</a>link end\n" + 
 240                         "    </p>\n" + 
 241                         "</html>\n" },
 242                 { "<p><a href=\"test.html\">text<table/></a> another<form/></p>",
 243                         "<p>\n" + 
 244                         "    <a href=\"test.html\">text\n" + 
 245                         "        <table></table>\n" + 
 246                         "    </a> another\n" + 
 247                         "    <form></form>\n" + 
 248                         "</p>\n" },
 249                 { MIXED_NODE_TYPES_XML,
 250                             "<root>\n" +
 251                             "    \n" +
 252                             "     t\n" +
 253                             "    <![CDATA[ ]]>\n" +
 254                             "    \n" +
 255                             "t   \n" +
 256                             "    \n" +
 257                             "    <child1></child1>\n" +
 258                             "    \n" +
 259                             "    t\n" +
 260                             "    <!-- test comment -->\n" +
 261                             "    <child2></child2>\n" +
 262                             "    <child5>\n" +
 263                             "        \n" +
 264                             "        t\n" +
 265                             "        <?target1 test>\n" +
 266                             "        <child51>\n" +
 267                             "            <child511>t</child511>\n" +
 268                             "        </child51>\n" +
 269                             "        <?target1 test>\n" +
 270                             "        \n" +
 271                             "        t\n" +
 272                             "    \n" +
 273                             "    </child5>\n" +
 274                             "</root>\n" } };
 275     }
 276 
 277     /*
 278      * @bug 8087303
 279      * Transform to HTML, test Pretty Print for HTML.
 280      *
 281      */
 282     @Test(dataProvider = "html-data")
 283     public void testTransformToHTML(String source, String expected) throws Exception {
 284         Transformer transformer = TransformerFactory.newInstance().newTransformer();
 285         transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
 286         transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
 287         transformer.setOutputProperty(OutputKeys.METHOD, "html");
 288         transformer.setOutputProperty(OutputKeys.INDENT, "yes");
 289 
 290         StringWriter writer = new StringWriter();
 291         transformer.transform(new StreamSource(new StringReader(source)), new StreamResult(writer));
 292        assertEquals(writer.toString().replaceAll("\r\n", "\n"), expected);
 293     }
 294 
 295     @Test
 296     public void testLSSerializerFormatPrettyPrint() {
 297 
 298         final String XML_DOCUMENT = "<?xml version=\"1.0\" encoding=\"UTF-16\"?>\n"
 299                 + "<hello>before child element<child><children/><children/></child>after child element</hello>";
 300         /**JDK-8035467
 301          * no newline in default output
 302          */
 303         final String XML_DOCUMENT_DEFAULT_PRINT =
 304                 "<?xml version=\"1.0\" encoding=\"UTF-16\"?>"
 305                 + "<hello>"
 306                 + "before child element"
 307                 + "<child><children/><children/></child>"
 308                 + "after child element</hello>";
 309 
 310         final String XML_DOCUMENT_PRETTY_PRINT = "<?xml version=\"1.0\" encoding=\"UTF-16\"?><hello>\n" +
 311                 "    before child element\n" +
 312                 "    <child>\n" +
 313                 "        <children/>\n" +
 314                 "        <children/>\n" +
 315                 "    </child>\n" +
 316                 "    after child element\n" +
 317                 "</hello>\n";
 318 
 319         // it all begins with a Document
 320         DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
 321         DocumentBuilder documentBuilder = null;
 322         try {
 323             documentBuilder = documentBuilderFactory.newDocumentBuilder();
 324         } catch (ParserConfigurationException parserConfigurationException) {
 325             parserConfigurationException.printStackTrace();
 326             Assert.fail(parserConfigurationException.toString());
 327         }
 328         Document document = null;
 329 
 330         StringReader stringReader = new StringReader(XML_DOCUMENT);
 331         InputSource inputSource = new InputSource(stringReader);
 332         try {
 333             document = documentBuilder.parse(inputSource);
 334         } catch (SAXException saxException) {
 335             saxException.printStackTrace();
 336             Assert.fail(saxException.toString());
 337         } catch (IOException ioException) {
 338             ioException.printStackTrace();
 339             Assert.fail(ioException.toString());
 340         }
 341 
 342         // query DOM Interfaces to get to a LSSerializer
 343         DOMImplementation domImplementation = documentBuilder.getDOMImplementation();
 344         DOMImplementationLS domImplementationLS = (DOMImplementationLS) domImplementation;
 345         LSSerializer lsSerializer = domImplementationLS.createLSSerializer();
 346 
 347         System.out.println("Serializer is: " + lsSerializer.getClass().getName() + " " + lsSerializer);
 348 
 349         // get configuration
 350         DOMConfiguration domConfiguration = lsSerializer.getDomConfig();
 351 
 352         // query current configuration
 353         Boolean defaultFormatPrettyPrint = (Boolean) domConfiguration.getParameter(DOM_FORMAT_PRETTY_PRINT);
 354         Boolean canSetFormatPrettyPrintFalse = (Boolean) domConfiguration.canSetParameter(DOM_FORMAT_PRETTY_PRINT, Boolean.FALSE);
 355         Boolean canSetFormatPrettyPrintTrue = (Boolean) domConfiguration.canSetParameter(DOM_FORMAT_PRETTY_PRINT, Boolean.TRUE);
 356 
 357         System.out.println(DOM_FORMAT_PRETTY_PRINT + " default/can set false/can set true = " + defaultFormatPrettyPrint + "/"
 358                 + canSetFormatPrettyPrintFalse + "/" + canSetFormatPrettyPrintTrue);
 359 
 360         // test values
 361         assertEquals(defaultFormatPrettyPrint, Boolean.FALSE, "Default value of " + DOM_FORMAT_PRETTY_PRINT + " should be " + Boolean.FALSE);
 362 
 363         assertEquals(canSetFormatPrettyPrintFalse, Boolean.TRUE, "Can set " + DOM_FORMAT_PRETTY_PRINT + " to " + Boolean.FALSE + " should be "
 364                 + Boolean.TRUE);
 365 
 366         assertEquals(canSetFormatPrettyPrintTrue, Boolean.TRUE, "Can set " + DOM_FORMAT_PRETTY_PRINT + " to " + Boolean.TRUE + " should be "
 367                 + Boolean.TRUE);
 368 
 369         // get default serialization
 370         String prettyPrintDefault = lsSerializer.writeToString(document);
 371         System.out.println("(default) " + DOM_FORMAT_PRETTY_PRINT + "==" + (Boolean) domConfiguration.getParameter(DOM_FORMAT_PRETTY_PRINT)
 372                 + ": \n\"" + prettyPrintDefault + "\"");
 373 
 374         assertEquals(prettyPrintDefault, XML_DOCUMENT_DEFAULT_PRINT, "Invalid serialization with default value, " + DOM_FORMAT_PRETTY_PRINT + "=="
 375                 + (Boolean) domConfiguration.getParameter(DOM_FORMAT_PRETTY_PRINT));
 376 
 377         // configure LSSerializer to not format-pretty-print
 378         domConfiguration.setParameter(DOM_FORMAT_PRETTY_PRINT, Boolean.FALSE);
 379         String prettyPrintFalse = lsSerializer.writeToString(document);
 380         System.out.println("(FALSE) " + DOM_FORMAT_PRETTY_PRINT + "==" + (Boolean) domConfiguration.getParameter(DOM_FORMAT_PRETTY_PRINT)
 381                 + ": \n\"" + prettyPrintFalse + "\"");
 382 
 383         assertEquals(prettyPrintFalse, XML_DOCUMENT_DEFAULT_PRINT, "Invalid serialization with FALSE value, " + DOM_FORMAT_PRETTY_PRINT + "=="
 384                 + (Boolean) domConfiguration.getParameter(DOM_FORMAT_PRETTY_PRINT));
 385 
 386         // configure LSSerializer to format-pretty-print
 387         domConfiguration.setParameter(DOM_FORMAT_PRETTY_PRINT, Boolean.TRUE);
 388         String prettyPrintTrue = lsSerializer.writeToString(document);
 389         System.out.println("(TRUE) " + DOM_FORMAT_PRETTY_PRINT + "==" + (Boolean) domConfiguration.getParameter(DOM_FORMAT_PRETTY_PRINT)
 390                 + ": \n\"" + prettyPrintTrue + "\"");
 391 
 392         assertEquals(prettyPrintTrue, XML_DOCUMENT_PRETTY_PRINT, "Invalid serialization with TRUE value, " + DOM_FORMAT_PRETTY_PRINT + "=="
 393                 + (Boolean) domConfiguration.getParameter(DOM_FORMAT_PRETTY_PRINT));
 394     }
 395 
 396     private String serializerWrite(Node xml) throws Exception {
 397         DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();
 398         DOMImplementationLS domImplementation = (DOMImplementationLS) registry.getDOMImplementation("LS");
 399         StringWriter writer = new StringWriter();
 400         LSOutput formattedOutput = domImplementation.createLSOutput();
 401         formattedOutput.setCharacterStream(writer);
 402         LSSerializer domSerializer = domImplementation.createLSSerializer();
 403         domSerializer.getDomConfig().setParameter(DOM_FORMAT_PRETTY_PRINT, true);
 404         domSerializer.getDomConfig().setParameter("xml-declaration", false);
 405         domSerializer.write(xml, formattedOutput);
 406         return writer.toString();
 407     }
 408 
 409     private String transform(Node xml) throws Exception {
 410         Transformer transformer = TransformerFactory.newInstance().newTransformer();
 411         transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
 412         transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
 413         transformer.setOutputProperty(OutputKeys.INDENT, "yes");
 414         StringWriter writer = new StringWriter();
 415         transformer.transform(new DOMSource(xml), new StreamResult(writer));
 416         return writer.toString();
 417     }
 418 
 419     private Document toXmlDocument(String xmlString) throws Exception {
 420         InputSource xmlInputSource = new InputSource(new StringReader(xmlString));
 421         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 422         dbf.setValidating(true);
 423         DocumentBuilder xmlDocumentBuilder = dbf.newDocumentBuilder();
 424         Document node = xmlDocumentBuilder.parse(xmlInputSource);
 425         return node;
 426     }
 427 
 428     private Text newTextNode(String text) throws Exception {
 429         DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
 430         return db.newDocument().createTextNode(text);
 431     }
 432 
 433     private Document createDocWithSequentTextNodes() throws Exception {
 434         DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
 435         Document doc = db.newDocument();
 436         Node root = doc.createElement("root");
 437         doc.appendChild(root);
 438         root.appendChild(doc.createTextNode(" "));
 439         root.appendChild(doc.createTextNode("t"));
 440         root.appendChild(doc.createTextNode("\n"));
 441         root.appendChild(doc.createTextNode("t"));
 442         root.appendChild(doc.createTextNode("   "));
 443         Node child1 = doc.createElement("child1");
 444         root.appendChild(child1);
 445         child1.appendChild(doc.createTextNode(" "));
 446         child1.appendChild(doc.createTextNode("\n"));
 447         root.appendChild(doc.createTextNode("t"));
 448         Node child2 = doc.createElement("child2");
 449         root.appendChild(child2);
 450         child2.appendChild(doc.createTextNode(" "));
 451         root.appendChild(doc.createTextNode(" "));
 452         Node child3 = doc.createElement("child3");
 453         root.appendChild(child3);
 454         child3.appendChild(doc.createTextNode(" "));
 455         root.appendChild(doc.createTextNode(" "));
 456         Node child4 = doc.createElement("child4");
 457         root.appendChild(child4);
 458         child4.appendChild(doc.createTextNode(" "));
 459 
 460         root.appendChild(doc.createTextNode(" "));
 461         Node child5 = doc.createElement("child5");
 462         root.appendChild(child5);
 463         child5.appendChild(doc.createTextNode("t"));
 464 
 465         Node child51 = doc.createElement("child51");
 466         child5.appendChild(child51);
 467         child51.appendChild(doc.createTextNode(" "));
 468         Node child511 = doc.createElement("child511");
 469         child51.appendChild(child511);
 470         child511.appendChild(doc.createTextNode("t"));
 471         child51.appendChild(doc.createTextNode(" "));
 472         child5.appendChild(doc.createTextNode("t"));
 473 
 474         root.appendChild(doc.createTextNode(" "));
 475         root.appendChild(doc.createComment(" test comment "));
 476         root.appendChild(doc.createTextNode(" \n"));
 477         root.appendChild(doc.createComment(" "));
 478         root.appendChild(doc.createTextNode("\n"));
 479         root.appendChild(doc.createProcessingInstruction("target1", "test"));
 480         root.appendChild(doc.createTextNode(" "));
 481         root.appendChild(doc.createTextNode(" "));
 482         return doc;
 483     }
 484 
 485     private static final String DOM_FORMAT_PRETTY_PRINT = "format-pretty-print";
 486 
 487     private static final String MIXED_NODE_TYPES_XML = "<root>\n" +
 488             "     t<![CDATA[ ]]>\n" +
 489             "t   \n" +
 490             "    <child1/>\n" +
 491             "    t<!-- test comment -->\n" +
 492             "    <child2/>\n" +
 493             "    <child5>\n" +
 494             "        t<?target1 test?>\n" +
 495             "        <child51>\n" +
 496             "            <child511>t</child511>\n" +
 497             "        </child51><?target1 test?>\n" +
 498             "        t\n" +
 499             "    </child5>\n" +
 500             "    \n" +
 501             "</root> \n";
 502 }