Qual è il modo più breve per stampare un documento org.w3c.dom.Document su stdout?


103

Qual è il modo più semplice per stampare graziosamente (ovvero formattato) a org.w3c.dom.Documentsu stdout?

Risposte:


186

Call printDocument(doc, System.out), dove quel metodo assomiglia a questo:

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-amountÈ facoltativo e potrebbe non funzionare con la tua configurazione particolare)


64
Non è ironico che questo sia il modo "più semplice" per stampare semplicemente un documento XML in Java?
Thomas

7
d'altra parte hai un sacco di controllo;)
Bozho

2
Brillante! E sì, è un po 'troppo testo ma è chiarissimo quali sono le opzioni selezionate ed Eclipse / Netbeans ti aiutano davvero a scriverlo. Mostrami una versione più piccola e ti dico cosa non può fare. Peggio ancora, ti dirò dove hai bisogno di 3 round di debug per farlo bene ...
Peter Kriens

4
Giuro su dio Java .. fammi scrivere un numero ridicolo di righe di codice per qualcosa che può essere fatto in una o due in altre lingue ... anche con il pieno controllo ..
l46kok

Ma se il vostro XML contiene caratteri astrali, e si utilizza Xalan, nota issues.apache.org/jira/browse/XALANJ-2419 e vedere anche stackoverflow.com/a/11987283/1031689
JasonPlutext

13

Che ne dite di:

OutputFormat format = new OutputFormat(doc);
format.setIndenting(true);
XMLSerializer serializer = new XMLSerializer(System.out, format);
serializer.serialize(doc);

8
Sebbene più facile, questo approccio richiede Xerces
Pace

3
Posso aggiungere che oggi XMLSerializer e OutputFormat sono deprecati
Vokail

9

Prova jcabi-xml con una fodera:

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

Questa è la dipendenza di cui hai bisogno:

<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
Apprezzo che la Q chieda il più breve, ma (a beneficio di chiunque altro) forse potresti elaborare la tua risposta per spiegare cosa sta succedendo?
Andrew

html -> head -> meta -> title -> body -> Se metto uno spazio di stringa poiché lo spaziatore sopra è il risultato è quello che ottengo. È quello che intende fare? Una stampa completa dell'XML è ciò che è necessario penso quando significa abbastanza stampato.
jeraldfdo

0

Ciò restituirà un output ben formattato utilizzando discesa / salita ricorsiva.

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

Questo è molto incompleto.
Andrew

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.