8

我正在尝试缩进由 Transformer 生成的 XML。除了第一个节点 - 文档元素外,所有 DOM 节点都按预期缩进。文档元素不在新行中开始,只是在 XML 声明之后连接。

当我移至 java 1.7 时出现此错误,使用 java 1.6 或 1.5 时不会发生。

我的代码:

ByteArrayOutputStream s = new OutputStreamWriter(out, "utf-8");

TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount","4");

transformer.transform(new DOMSource(doc), new StreamResult(s));

输出:

<?xml version="1.0" encoding="UTF-8"?><a>
       <b>bbbbb</b>
 </a>

任何人都知道为什么?

顺便说一句,当我添加属性

transformer.setOutputProperty(OutputKeys.STANDALONE, "yes");

它按预期工作,但 xml 声明已更改,它现在也具有独立属性,我不想更改 xml 声明..

4

4 回答 4

15

好的 ,

我在 Java API 中发现了这个:

如果指定了 doctype-system 属性,则 xml 输出方法应在第一个元素之前立即输出文档类型声明。

所以我使用了这个属性

 transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "yes");

它解决了我的问题而没有改变我的 xml 声明。

谢谢。

于 2013-08-15T11:38:00.113 回答
3

Xalan 在某些时候改变了 XML 声明后换行符的行为。

OpenJDK(因此也包括 Oracle JDK)已针对此问题实施了一种解决方法。可以通过在对象上设置特殊属性来启用此解决方法Transformer

try {
    transformer.setOutputProperty("http://www.oracle.com/xml/is-standalone", "yes");
} catch (IllegalArgumentException e) {
    // Might be thrown by JDK versions not implementing the workaround.
} 

这样,旧的行为(在 XML 声明之后打印一个换行符)被恢复,而无需向 XML 声明添加独立属性。

于 2016-08-04T17:20:24.733 回答
1

对我来说,在编写 XML 之前WriterOutputStream之前编写 XML 声明并告诉转换器省略声明是唯一有效的方法。保留间距的唯一其他解决方案似乎是 VTD-XML 库。

    StringBuilder sb = new StringBuilder();
    sb.append("<?xml version=\"").append(doc.getXmlVersion()).append("\"");
    sb.append(" encoding=\"").append(doc.getXmlEncoding()).append("\"");
    if (doc.getXmlStandalone()) {
        sb.append(" standalone=\"").append("" + doc.getXmlStandalone()).append("\"");
    }
    sb.append("?>").append("\n");

    writer.write(sb.toString());
            TransformerFactory tf = TransformerFactory.newInstance();
    try {
        Transformer transformer = tf.newTransformer();
        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
    }
    catch (Exception e)  {
    //snipped out for brevity
    }
于 2017-04-10T23:51:38.343 回答
0

这似乎是 Java 中 XML 实现的问题(错误)。在 XML 声明之后获得换行符的唯一方法是显式指定standalone属性。您可以将其设置为no,这是隐式默认值,即使在不使用 DTD 时它完全不相关。

于 2016-04-04T07:44:44.920 回答