【问题标题】:Serializing Java DOM Document to XML: Add CData Elements将 Java DOM 文档序列化为 XML:添加 CData 元素
【发布时间】:2014-04-25 07:17:31
【问题描述】:

我正在使用 SAX 解析器构建 XML DOM 文档。我已经编写了处理startCDATAendCDATA 方法的方法,并且在endCDATA 方法中我构造了一个新的CDATA 部分,如下所示:

public void onEndCData() {
    xmlStructure.cData = false;
    Document document = xmlStructure.xmlResult.document;
    Element element = (Element) xmlStructure.xmlResult.stack.peek();
    CDATASection section = document.createCDATASection(xmlStructure.stack.peek().characters);
    element.appendChild(section);
}

当我将其序列化为 XML 文件时,我使用以下行来配置转换器:

transformer.setOutputProperty(OutputKeys.CDATA_SECTION_ELEMENTS, "con:setting");

在我的 XML 文件中永远不会出现 <![CDATA[ 标记,而是将所有备份转义为 ><,这对于其他工具来说没问题,但对于需要阅读文件也是如此。我很肯定“con:setting”标签是正确的。那么命名空间前缀可能有问题吗?

另外this question 表示不能省略 CDATA_SECTION_ELEMENTS 属性,并且通常在不转义数据的情况下序列化所有 CDATA 节点。该信息是否正确,或者答案作者可能不知道其他方法?

更新:看来我的代码有误。当使用 document.createCDATASection() 函数,然后使用 Transformer 序列化代码时,它DOES 输出 CDATA 标记,即使没有在转换器中使用 CDATA_SECTION_ELEMENTS 属性。

【问题讨论】:

  • 您不能使用运行 XSLT 样式表的 Transformer 从输入中保留 CDATA,也许对于无操作转换器的规则不同(或者更可能结果将是特定于处理器的)。
  • 我现在在保存的 XML 文件中获取 CDATA 标记时它们似乎是这样的。
  • 看看你是否在不同的TransformerFactory 实现中得到相同的行为会很有趣——例如,如果你切换到 Saxon,no-op Transformer 是否仍然保留 CDATA?我在 JAXP 规范中看不到任何定义它的任何内容,但我知道 DOM LS 机制肯定会在所有情况下按照您的要求工作。

标签: java xml dom sax


【解决方案1】:

看起来你有一个命名空间感知 DOM。 docs 表示你需要提供元素的Qualified Name Representation

private static String qualifiedNameRepresentation(Element e) {
  String ns = e.getNamespaceURI();
  String local = e.getLocalName();
  return (ns == null) ? local : '{' + ns + '}' + local;
}

因此,该属性的值将采用{http://your.conn.namespace}setting 的形式。

【讨论】:

    【解决方案2】:

    在这一行

    transformer.setOutputProperty(OutputKeys.CDATA_SECTION_ELEMENTS, "con:setting");
    

    尝试将"con:setting" 替换为"{http://con.namespace/}setting"

    使用适当的命名空间

    【讨论】:

      【解决方案3】:

      您可以尝试使用 DOM-native "load and save" mechanism,而不是使用无操作 Transformer 来序列化您的 DOM 树,它应该保留 DOM 树中的 CDATASection 节点并将它们作为 CDATA 部分写入生成的 XML。

      DOMImplementationLS ls = (DOMImplementationLS)document.getImplementation();
      LSOutput output = ls.createLSOutput();
      LSSerializer ser = ls.createLSSerializer();
      try (FileOutputStream outStream = new FileOutputStream(...)) {
        output.setByteStream(outStream);
        output.setEncoding("UTF-8");
        ser.write(document, output);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-03-16
        • 2016-10-05
        • 2023-04-02
        • 1970-01-01
        • 1970-01-01
        • 2011-07-24
        • 2015-10-08
        • 1970-01-01
        相关资源
        最近更新 更多