Jaki jest najkrótszy sposób, aby ładnie wydrukować dokument org.w3c.dom.Document na standardowe wyjście?

103

Jaki jest najłatwiejszy sposób na ładne wydrukowanie (czyli sformatowanie) a org.w3c.dom.Documentna standardowe wyjście?

Lecieć jak po sznurku
źródło

Odpowiedzi:

186

Call printDocument(doc, System.out), gdzie ta metoda wygląda następująco:

public static void printDocument(Document doc, OutputStream out) throws IOException, TransformerException {
    TransformerFactory tf = TransformerFactory.newInstance();
    Transformer transformer = tf.newTransformer();
    transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
    transformer.setOutputProperty(OutputKeys.METHOD, "xml");
    transformer.setOutputProperty(OutputKeys.INDENT, "yes");
    transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
    transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");

    transformer.transform(new DOMSource(doc), 
         new StreamResult(new OutputStreamWriter(out, "UTF-8")));
}

( indent-amountJest opcjonalny i może nie działać w Twojej konkretnej konfiguracji)

Bozho
źródło
64
Czy to nie ironia losu, że jest to „najłatwiejszy” sposób po prostu wydrukowania dokumentu XML w Javie?
Thomas
7
z drugiej strony masz dużo kontroli;)
Bozho
2
Znakomity! I tak, jest to trochę tekstu, ale jest krystalicznie jasne, jakie są wybrane opcje, a Eclipse / Netbeans naprawdę pomaga ci to napisać. Pokaż mi mniejszą wersję, a powiem ci, czego nie może zrobić. Gorzej, powiem ci, gdzie potrzebujesz 3 rund debugowania, aby zrobić to dobrze ...
Peter Kriens
4
Przysięgam, Java .. zmusić mnie do napisania absurdalnej liczby wierszy kodu dla czegoś, co można zrobić w jednym lub dwóch w innych językach ... również z pełną kontrolą ..
l46kok
Ale jeśli twój XML zawiera znaki astralne i używasz Xalana , zanotuj issue.apache.org/jira/browse/XALANJ-2419 i zobacz również stackoverflow.com/a/11987283/1031689
JasonPlutext
13

Co powiesz na:

OutputFormat format = new OutputFormat(doc);
format.setIndenting(true);
XMLSerializer serializer = new XMLSerializer(System.out, format);
serializer.serialize(doc);
Dennis
źródło
8
Chociaż łatwiejsze, to podejście wymaga Xerces
Tempo
3
Mogę dodać, że dziś XMLSerializer i OutputFormat są przestarzałe
Vokail
9

Wypróbuj jcabi-xml z jedną linijką :

String xml = new XMLDocument(document).toString();

Oto zależność, której potrzebujesz:

<dependency>
  <groupId>com.jcabi</groupId>
  <artifactId>jcabi-xml</artifactId>
  <version>0.14</version>
</dependency>
yegor256
źródło
4
private void printNode(Node rootNode, String spacer) {
    System.out.println(spacer + rootNode.getNodeName() + " -> " + rootNode.getNodeValue());
    NodeList nl = rootNode.getChildNodes();
    for (int i = 0; i < nl.getLength(); i++)
        printNode(nl.item(i), spacer + "   ");
}
Hannes
źródło
1
Doceniam, że Q pyta o jak najkrótsze, ale (z korzyścią dla kogokolwiek innego) może mógłbyś uściślić swoją odpowiedź, aby wyjaśnić, co się dzieje?
Andrew
html -> head -> meta -> title -> body -> Jeśli umieszczę spację ciągu, ponieważ powyższy spacer to wynik jest taki, jaki otrzymuję. Czy to jest to, co ma zrobić? Wydaje mi się, że pełny wydruk XML jest tym, co jest potrzebne, kiedy wydaje się być ładnie wydrukowany.
jeraldfdo
0

Zwróci to ładnie sformatowany wynik przy użyciu rekursywnego zejścia / wznoszenia.

private static boolean skipNL;
private static String printXML(Node rootNode) {
    String tab = "";
    skipNL = false;
    return(printXML(rootNode, tab));
}
private static String printXML(Node rootNode, String tab) {
    String print = "";
    if(rootNode.getNodeType()==Node.ELEMENT_NODE) {
        print += "\n"+tab+"<"+rootNode.getNodeName()+">";
    }
    NodeList nl = rootNode.getChildNodes();
    if(nl.getLength()>0) {
        for (int i = 0; i < nl.getLength(); i++) {
            print += printXML(nl.item(i), tab+"  ");    // \t
        }
    } else {
        if(rootNode.getNodeValue()!=null) {
            print = rootNode.getNodeValue();
        }
        skipNL = true;
    }
    if(rootNode.getNodeType()==Node.ELEMENT_NODE) {
        if(!skipNL) {
            print += "\n"+tab;
        }
        skipNL = false;
        print += "</"+rootNode.getNodeName()+">";
    }
    return(print);
}
znak
źródło
To jest bardzo niekompletne.
Andrew
-1

jeśli używasz dom4j, będzie to dom4JDOM.asString ()

Rockoder
źródło