【问题标题】:how to prevent XML Transformer from changing line endings如何防止 XML Transformer 改变行尾
【发布时间】:2013-01-07 20:42:36
【问题描述】:

我有一个编辑 xml 文件的方法。该方法的大致思路是:

public void process(Path anXmlFile) {
    try {
        anXmlFile= anXmlFile.normalize();
        log.debug("processing {}",anXmlFile);
        Document dom = buildDOM(anXmlFile.toFile());

        //do stuff with dom...
        //delete original file
        //and finally ...
        dom.normalize(); //so we get a more predictable order

        Transformer transformer = transformerFactory.newTransformer();
        transformer.setOutputProperty(OutputKeys.ENCODING,"UTF-8");
        transformer.setOutputProperty(OutputKeys.INDENT,"yes");
        Source source = new DOMSource(dom);
        Result result = new StreamResult(anXmlFile.toFile());
        transformer.transform(source, result);
    } catch (Exception e) {
        throw new IllegalStateException(e);
    }
}

我的问题是,如果我对在某一行打开并在下一行关闭的 xml 有一个多行注释(注意换行符):

<!-- this is a long comment[cr][lf] 
     that spans 2 lines -->

在我写出修改后的 DOM 之后,结果将是:

<!-- this is a long comment[cr] 
     that spans 2 lines -->

问题是 [cr][lf] 变成了 [cr]。 这是 xml 中唯一以这种方式受到影响的部分。所有其他行尾都与原始 ([cr][lf]) 相同 - 即使是我修改过的那些(我的代码不会更改 DOM 中的注释节点)。

我可以为我创建的 Transformer 提供任何配置选项来避免这种情况吗? 这都是使用 JDK 类完成的,不涉及 xml 库。

【问题讨论】:

  • XML 规范要求解析器的这种行为;请参阅End-of-Line Handling 部分。
  • @McDowell 哇,他们太傻了。是否有任何解析器可以选择忽略这一点并给我一致的换行符?
  • 但是,这是关于 DOM 树的序列化,因此该规范并不真正适用。
  • @forty-2 公平点,但我希望它解释了默认行为。我注意到LSSerializer 有一个设置行尾顺序的选项。

标签: java xml dom


【解决方案1】:

XML 规范要求 XML 处理器(解析器)用单个 \n 替换 \r\n 或仅替换 \r。因此,如果您检查您的 DOM 文本节点,您会发现您只有 \n 作为行尾。

在序列化 DOM 树时,大多数实现在编写 字符数据 中出现的换行符时使用平台默认值,或者它们为您提供了显式设置行尾字符串的选项。但是,注释文本不是字符数据;字符只是按原样写入,没有任何其他处理。至少,这是大多数序列化程序的行为方式。

如果它非常重要,您可以切换到 JDOM 并扩展 AbstractXMLOutputProcessor 以改变 cmets 的编写方式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-27
    • 1970-01-01
    • 2017-04-06
    • 1970-01-01
    • 1970-01-01
    • 2012-01-31
    • 1970-01-01
    相关资源
    最近更新 更多