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.