Каков самый короткий способ распечатать org.w3c.dom.Document в stdout?

103

Каков самый простой способ красиво распечатать (также отформатированный) org.w3c.dom.Documentв стандартный вывод?

облет
источник

Ответы:

186

Вызов printDocument(doc, System.out), где этот метод выглядит так:

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Необязательный и может не работать с вашей конкретной конфигурацией)

Божо
источник
64
Разве не парадоксально, что это «самый простой» способ просто распечатать XML-документ на Java?
Thomas
7
с другой стороны, у вас достаточно контроля;)
Bozho
2
Гениально! И да, это немного много текста, но совершенно ясно, каковы выбранные параметры, и Eclipse / Netbeans действительно поможет вам написать это. Покажите мне уменьшенную версию, и я скажу вам, чего она не может. Хуже того, я скажу вам, где вам нужно 3 раунда отладки, чтобы все получилось правильно ...
Питер Кринс
4
Богом клянусь, Java ... заставь меня написать нелепое количество строк кода для чего-то, что можно сделать на одном или двух других языках ... с полным контролем тоже ..
l46kok
Но если ваш XML содержит астральные символы и вы используете Xalan, обратите внимание на issues.apache.org/jira/browse/XALANJ-2419 и см. Также stackoverflow.com/a/11987283/1031689
JasonPlutext
13

Как насчет:

OutputFormat format = new OutputFormat(doc);
format.setIndenting(true);
XMLSerializer serializer = new XMLSerializer(System.out, format);
serializer.serialize(doc);
Деннис
источник
8
Хотя этот подход проще, для этого требуется Xerces
Pace
3
Я могу добавить, что сегодня XMLSerializer и OutputFormat устарели
Vokail
9

Попробуйте jcabi-xml с одним вкладышем:

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

Это необходимая вам зависимость:

<dependency>
  <groupId>com.jcabi</groupId>
  <artifactId>jcabi-xml</artifactId>
  <version>0.14</version>
</dependency>
Егор256
источник
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
Я ценю, что Q запрашивает самый короткий, но (в интересах кого-то еще), возможно, вы могли бы уточнить свой ответ, чтобы объяснить, что происходит?
Эндрю
html -> head -> meta -> title -> body -> Если я помещаю пробел строки в качестве разделителя выше, я получаю то, что я получаю. Это то, для чего он предназначен? Я думаю, что полная распечатка XML - это то, что нужно, когда это имеет в виду хорошо напечатанное.
Джеральдфдо
0

Это вернет красиво оформленный вывод с использованием рекурсивного спуска / подъема.

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);
}
отметка
источник
Это очень неполно.
Эндрю
-1

если вы используете dom4j, это будет dom4JDOM.asString ()

Рокодер
источник