由于移动到 java 1.7 Xml 文档元素不缩进

Posted

技术标签:

【中文标题】由于移动到 java 1.7 Xml 文档元素不缩进【英文标题】:Since moving to java 1.7 Xml Document Element does not indent 【发布时间】:2013-08-17 10:53:27 【问题描述】:

我正在尝试缩进由 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/xsltindent-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 声明..

【问题讨论】:

【参考方案1】:

好的,

我在 Java API 中找到了这个:

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

所以我使用了这个属性

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

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

谢谢。

【讨论】:

这几天一直在找:) 这对我不起作用。仅设置 DOCTYPE_PUBLIC=yes 不会使文档元素从新行开始。只有 STANDALONE=yes 或 no 做这件事,但我不想明确指定它,因为我不使用 DTD,我使用架构。【参考方案2】:

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

OpenJDK(以及 Oracle JDK)已经为这个问题实现了workaround。可以通过在 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 声明添加独立属性。

【讨论】:

【参考方案3】:

对我来说,在编写 XML 之前将 XML 声明写入 WriterOutputStream 并告诉转换器省略声明是唯一有效的方法。保留间距的唯一其他解决方案似乎是 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
    

【讨论】:

【参考方案4】:

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

【讨论】:

以上是关于由于移动到 java 1.7 Xml 文档元素不缩进的主要内容,如果未能解决你的问题,请参考以下文章

用于操作/编辑现有 xml 文档的最佳 java Xml 解析器

java Document生成和解析xml

XML基本概念及增删改查操作

元素添加到 DOM 时触发事件:JQuery Livequery Equivalent in 1.7

xml解析3种方式

xml解析3种方式