OutputKeys.INDENT不影响从其他文档复制的节点

时间:2012-07-28 17:36:13

标签: java xml dom

我将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>

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

感谢名单

2 个答案:

答案 0 :(得分:0)

输出缩进的效果被指定为实现定义。如果你不喜欢一个处理器处理它的方式,你总是可以尝试另一个处理器(在这种情况下意味着尝试撒克逊)。

答案 1 :(得分:0)

你很可能会发现&lt; foundNode&gt;的第一个孩子。是一个只包含换行符的文本节点。文本节点通常会阻止自动压头执行其工作,其中包括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中描述的约束。