将Java DOM文档序列化为XML:添加CData元素

时间:2014-04-25 07:17:31

标签: java xml dom sax

我正在使用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[标记的情况从未如此,而且所有支持都转发到&gt;&lt;,这对其他工具来说没有问题,但这是一个问题。那些需要阅读文件的人。我很肯定&#34; con:setting&#34;标签是正确的。那么命名空间前缀可能有问题吗?

同样this question表示无法省略CDATA_SECTION_ELEMENTS属性,并且通常序列化所有CDATA节点而不转义数据。这些信息是否正确,或者答案作者可能还没有其他方法可以识别?

更新:我的代码似乎有误。使用document.createCDATASection()函数,然后使用Transformer序列化代码时, DOES 输出CDATA标记,即使不使用变换器中的CDATA_SECTION_ELEMENTS属性。

3 个答案:

答案 0 :(得分:2)

看起来你有一个名称空间感知的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形式。

答案 1 :(得分:1)

在这一行

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

尝试用"con:setting"

替换"{http://con.namespace/}setting"

使用适当的命名空间

答案 2 :(得分:0)

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

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);
}