¿Cuál es la forma más corta de imprimir un documento org.w3c.dom.Document en stdout?

103

¿Cuál es la forma más fácil de imprimir bastante (también conocido como formateado) org.w3c.dom.Documenta en stdout?

flybywire
fuente

Respuestas:

186

Llame printDocument(doc, System.out), donde ese método se ve así:

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

(El indent-amountes opcional y podría no funcionar con su configuración particular)

Bozho
fuente
64
¿No es irónico que esa sea la forma "más fácil" de simplemente imprimir un documento XML en Java?
Thomas
7
por otro lado tienes mucho control;)
Bozho
2
¡Brillante! Y sí, es demasiado texto, pero está muy claro cuáles son las opciones seleccionadas y Eclipse / Netbeans realmente te ayudan a escribir esto. Muéstrame una versión más pequeña y te diré lo que no puede hacer. Peor aún, te diré dónde necesitas 3 rondas de depuración para hacerlo bien ...
Peter Kriens
4
Lo juro por Dios Java ... hazme escribir una cantidad ridícula de líneas de código para algo que se puede hacer en uno o dos en otros idiomas ... con control total también ..
l46kok
Pero si su XML contiene caracteres astrales y está utilizando Xalan, tenga en cuenta issues.apache.org/jira/browse/XALANJ-2419 y consulte también stackoverflow.com/a/11987283/1031689
JasonPlutext
13

Qué tal si:

OutputFormat format = new OutputFormat(doc);
format.setIndenting(true);
XMLSerializer serializer = new XMLSerializer(System.out, format);
serializer.serialize(doc);
Dennis
fuente
8
Si bien es más fácil, este enfoque requiere Xerces
Pace
3
Puedo agregar que hoy XMLSerializer y OutputFormat están en desuso
Vokail
9

Pruebe jcabi-xml con una línea:

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

Esta es la dependencia que necesita:

<dependency>
  <groupId>com.jcabi</groupId>
  <artifactId>jcabi-xml</artifactId>
  <version>0.14</version>
</dependency>
yegor256
fuente
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
fuente
1
Aprecio que la Q pida la más corta, pero (en beneficio de cualquier otra persona) ¿quizás podrías elaborar tu respuesta para explicar qué está pasando?
Andrew
html -> head -> meta -> title -> body -> Si coloco un espacio de cadena como el espaciador de arriba, el resultado es lo que obtengo. ¿Es lo que pretende hacer? Una impresión completa del XML es lo que se necesita, creo, cuando significa bastante impreso.
jeraldfdo
0

Esto devolverá una salida bien formateada utilizando descenso / ascenso recursivo.

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);
}
marca
fuente
Esto es muy incompleto.
Andrew
-1

si usa dom4j, sería dom4JDOM.asString ()

Rockoder
fuente