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?

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)


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

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>

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

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

Ceci est très incomplet.
Andrew

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.