2

我将 XML 文件读入 org.w3c.dom.Document,通过 getElementsByTagName 找到一个节点,以这种方式从其他文档追加子节点:

foundNode.appendChild(document.adoptNode(othersDocumentNode.cloneNode(true)));

之后,我将结果保存到 StringWriter:

Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "20");
transformer.transform(
    new DOMSource(document),
    new StreamResult(out)
);

结果我得到这样的文件:

<document>
                   <foundNode>
<nestedContent>
  <content/>
</nestedContent>
                   </foundonde>
</document>

即格式化不会影响嵌套内容。我希望所有文档都被格式化。我怎样才能做到这一点?

谢谢

4

2 回答 2

0

输出缩进的效果被指定为实现定义。如果您不喜欢一个处理器处理它的方式,您可以随时尝试另一个(在这种情况下,尝试 Saxon)。

于 2012-07-29T12:46:40.937 回答
0

您很可能会发现 <foundNode> 的第一个子节点是一个文本节点,它只包含一个换行符。文本节点通常会阻止自动缩进器完成其工作,这包括 a) 换行和 b) 插入适当的缩进。当然,它是通过插入自己的文本节点来做到这一点的,因此人们可以看到为什么通常编写缩进器来避免在存在现有文本节点的情况下缩进。

但是因为保留了换行符,所以看起来压痕确实有效,只是它不遵守缩进宽度配置。

你能做些什么来解决这个问题取决于你任务的更广泛的背景。例如,您可以从嵌套内容中递归地修剪空白文本节点。

private static void removeWhitespace(Element el) {
    NodeList nl = el.getChildNodes();
    for (int i = 0; i < nl.getLength(); i++) {
        Node n = nl.item(i);
        if (n.getNodeType() == Node.TEXT_NODE) {
            String text = n.getTextContent();
            String trimmed = text.trim();
            if (trimmed.isEmpty())
                el.removeChild(n);
            else if (trimmed.length() < text.length())
                n.setTextContent(trimmed);
        }
        if (n.getNodeType() == Node.ELEMENT_NODE)
            removeWhitespace((Element) n);
    }
}

(注意:这只是一个原始示例。如果您知道文本节点中没有任何有效负载数据,它就可以工作。)

在解析其他文档时调用DocumentBuilderFactory.setIgnoringElementContentWhitespace乍一看可能看起来很诱人,但请注意 JavaDoc 中描述的约束。

于 2012-07-29T13:34:12.257 回答