Quel est le moyen le plus court d'imprimer un document org.w3c.dom.Document sur stdout?

103

Quelle est la manière la plus simple d'imprimer un joli format (aka formaté) org.w3c.dom.Documentsur stdout?

flybywire
la source

Réponses:

186

Appelez printDocument(doc, System.out), où cette méthode ressemble à ceci:

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

(Le indent-amountest facultatif et peut ne pas fonctionner avec votre configuration particulière)

Bozho
la source
64
N'est-il pas ironique que ce soit le moyen le plus "simple" d'imprimer simplement un document XML en Java?
Thomas
7
par contre, vous avez beaucoup de contrôle;)
Bozho
2
Brillant! Et oui, c'est un peu beaucoup de texte, mais les options sélectionnées sont claires et Eclipse / Netbeans vous aide vraiment à écrire cela. Montrez-moi une version plus petite et je vous dirai ce qu'il ne peut pas faire. Pire encore, je vais vous dire où vous avez besoin de 3 tours de débogage pour bien faire les choses ...
Peter Kriens
4
Je jure devant Dieu Java .. fais-moi écrire un nombre ridicule de lignes de code pour quelque chose qui peut être fait dans une ou deux dans d'autres langues ... avec un contrôle total aussi ..
l46kok
Mais si votre XML contient des caractères astraux et que vous utilisez Xalan, notez issues.apache.org/jira/browse/XALANJ-2419 et consultez également stackoverflow.com/a/11987283/1031689
JasonPlutext
13

Que diriez-vous:

OutputFormat format = new OutputFormat(doc);
format.setIndenting(true);
XMLSerializer serializer = new XMLSerializer(System.out, format);
serializer.serialize(doc);
Dennis
la source
8
Bien que plus simple, cette approche nécessite Xerces
Pace
3
Je peux ajouter qu'aujourd'hui XMLSerializer et OutputFormat sont obsolètes
Vokail
9

Essayez jcabi-xml avec une seule doublure:

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

Voici la dépendance dont vous avez besoin:

<dependency>
  <groupId>com.jcabi</groupId>
  <artifactId>jcabi-xml</artifactId>
  <version>0.14</version>
</dependency>
yegor256
la source
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
la source
1
J'apprécie que le Q demande le plus court, mais (pour le bénéfice de quelqu'un d'autre) peut-être pourriez-vous élaborer votre réponse pour expliquer ce qui se passe?
Andrew
html -> head -> meta -> title -> body -> Si je place un espace de chaîne comme l'espaceur ci-dessus, le résultat est ce que j'obtiens. Est-ce ce que son intention est de faire? Une impression complète du XML est ce qui est nécessaire, je pense, quand cela signifie assez imprimé.
jeraldfdo
0

Cela retournera une sortie joliment formatée en utilisant une descente / remontée récursive.

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);
}
marque
la source
Ceci est très incomplet.
Andrew
-1

si vous utilisez dom4j, ce serait dom4JDOM.asString ()

Rockoder
la source