Apa cara terpendek untuk mencetak dokumen org.w3c.dom.Document ke stdout?

103

Apa cara termudah untuk mencetak cantik (alias diformat) org.w3c.dom.Documentke stdout?

flybywire
sumber

Jawaban:

186

Panggil printDocument(doc, System.out), di mana metode itu terlihat seperti ini:

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")));
}

(Ini indent-amountopsional, dan mungkin tidak berfungsi dengan konfigurasi khusus Anda)

Bozho
sumber
64
Bukankah ironis bahwa itu cara "termudah" untuk hanya mencetak dokumen XML di Java?
Thomas
7
di sisi lain Anda memiliki banyak kendali;)
Bozho
2
Cemerlang! Dan ya, ini sedikit banyak teks tetapi sangat jelas pilihan apa yang dipilih dan Eclipse / Netbeans sangat membantu Anda menulis ini. Tunjukkan versi yang lebih kecil dan saya beri tahu Anda apa yang tidak bisa dilakukannya. Lebih buruk lagi, saya akan memberi tahu Anda di mana Anda membutuhkan 3 putaran debugging untuk melakukannya dengan benar ...
Peter Kriens
4
Aku bersumpah demi Tuhan Java .. membuatku menulis sejumlah baris kode yang konyol untuk sesuatu yang bisa dilakukan dalam satu atau dua bahasa lain ... dengan kontrol penuh juga ..
l46kok
Tetapi jika XML Anda berisi karakter astral, dan Anda menggunakan Xalan, catat issues.apache.org/jira/browse/XALANJ-2419 dan lihat juga stackoverflow.com/a/11987283/1031689
JasonPlutext
13

Bagaimana tentang:

OutputFormat format = new OutputFormat(doc);
format.setIndenting(true);
XMLSerializer serializer = new XMLSerializer(System.out, format);
serializer.serialize(doc);
Dennis
sumber
8
Meskipun lebih mudah, pendekatan ini membutuhkan Xerces
Pace
3
Saya dapat menambahkan bahwa hari ini XMLSerializer dan OutputFormat sudah tidak digunakan lagi
Vokail
9

Coba jcabi-xml dengan satu liner:

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

Ini adalah ketergantungan yang Anda butuhkan:

<dependency>
  <groupId>com.jcabi</groupId>
  <artifactId>jcabi-xml</artifactId>
  <version>0.14</version>
</dependency>
yegor256
sumber
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
sumber
1
Saya menghargai bahwa Q meminta yang terpendek, tetapi (untuk kepentingan orang lain) mungkin Anda dapat menguraikan jawaban Anda untuk menjelaskan apa yang terjadi?
Andrew
html -> head -> meta -> title -> body -> Jika saya menempatkan spasi dari string seperti spacer di atas adalah hasil yang saya dapatkan. Apakah itu yang dimaksudkan untuk dilakukan? Sebuah cetakan penuh dari XML adalah apa yang dibutuhkan, saya pikir jika itu berarti cukup dicetak.
jeraldfdo
0

Ini akan mengembalikan keluaran yang diformat dengan baik dengan menggunakan penurunan / pendakian rekursif.

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);
}
Menandai
sumber
Ini sangat tidak lengkap.
Andrew
-1

jika Anda menggunakan dom4j, itu akan menjadi dom4JDOM.asString ()

Rockoder
sumber