由于移动到 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 声明写入 Writer
或 OutputStream
并告诉转换器省略声明是唯一有效的方法。保留间距的唯一其他解决方案似乎是 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 解析器