我尝试使用Saxon代替JDK的默认实现(Xalan I guess)进行XML转换和Xpath。在我的代码中,我使用document.createCDATASection(data)方法创建CDATA节点。代码如下所示:
CDATASection cdata = doc.createCDATASection("data");
Node valueNode = node.appendChild(doc.createElement("value"));
valueNode.appendChild(cdata);
其中node是我的XML中的一些随机节点。 它适用于JDK的默认实现,结果XML看起来像:
<node>
<value><![CDATA[data]]></value>
</node>
如果我包含Saxon maven工件,那么相同的代码开始表现得很奇怪(请注意它只是包含和工厂选择/实例化是默认的,就像之前一样)并且所有cdata节点都被视为简单的文本节点,即XML变为:
<node>
<value>data</value>
</node>
在检索时会引起问题,因为该代码专门检查cdata元素,后者已被删除。我不确定为什么会这样(看起来我没有正确使用它)。我也尝试从我的POM(Saxon的传递依赖)中排除Xerces文物,但没有运气。此外,验证了从JDK本身使用DocumentBuilderFactory等的实现类。如果我做错了,请专家帮助我。
提前致谢。
答案 0 :(得分:1)
我猜你的应用程序可能正在进行从DOMSource到StreamResult的JAXP身份转换,以便序列化DOM。 JAXP身份转换的Saxon实现使用XSLT的序列化规则,这些规则具有丢弃CDATA部分的效果。这与JAXP完全一致,即使它不是默认的JDK实现。
如果你依赖于JAXP身份转换器的特定实现的行为,那么你不应该编写你的应用程序来获取在类路径上正好存在的任何实现;你应该明确地实例化你想要的实现。
当然,如果调用身份转换的代码是您自己不编写且无法轻易更改的内容,那么这可能很难。在这种情况下,最好的方法是设置系统属性javax.xml.transform.TransformerFactory以选择Xalan,并且在那里调用Saxon,明确地执行它而不是依赖于JAXP工厂搜索。