Qual é a maneira mais curta de imprimir um org.w3c.dom.Document em stdout?


103

Qual é a maneira mais fácil de imprimir corretamente (também conhecido como formatado) org.w3c.dom.Documentem stdout?

Respostas:


186

Call printDocument(doc, System.out), onde esse método se parece com este:

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

(O indent-amounté opcional e pode não funcionar com sua configuração específica)


64
Não é irônico que essa seja a maneira "mais fácil" de simplesmente imprimir um documento XML em Java?
Thomas

7
por outro lado, você tem bastante controle;)
Bozho

2
Brilhante! E sim, é um pouco demais de texto, mas é cristalino quais são as opções selecionadas e Eclipse / Netbeans realmente ajudam você a escrever isso. Mostre-me uma versão menor e direi o que ela não pode fazer. Pior, direi onde você precisa de 3 rodadas de depuração para acertar ...
Peter Kriens

4
Juro por Deus, Java .. me faça escrever um número ridículo de linhas de código para algo que pode ser feito em uma ou duas em outras linguagens ... com controle total também ..
l46kok

Mas se seu XML contiver caracteres astrais e você estiver usando Xalan, observe issues.apache.org/jira/browse/XALANJ-2419 e consulte também stackoverflow.com/a/11987283/1031689
JasonPlutext

13

E se:

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

8
Embora mais fácil, essa abordagem requer Xerces
Pace

3
Posso acrescentar que hoje XMLSerializer e OutputFormat estão obsoletos
Vokail

9

Experimente jcabi-xml com um liner:

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

Esta é a dependência de que você precisa:

<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
Agradeço que o Q peça o mais curto, mas (para o benefício de qualquer outra pessoa) talvez você possa elaborar sua resposta para explicar o que está acontecendo?
Andrew

html -> head -> meta -> title -> body -> Se eu colocar um espaço de string como o espaçador acima é o resultado que obtenho. É o que se pretende fazer? Uma impressão completa do XML é o que é necessário, eu acho, quando significa bem impresso.
jeraldfdo

0

Isso retornará uma saída bem formatada usando descida / subida recursiva.

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

Isso está muito incompleto.
Andrew,

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.