深度复制Saxon Java外部函数中的XML节点

时间:2014-03-26 21:13:38

标签: java xml xslt saxon

我正在编写一个应该从XSLT样式表调用的Java外部函数。我打算返回一个传递给我的函数的修改节点作为参数。但是,由于我获得The Saxon DOM cannot be updated,因此我无法深度复制节点。 (我认为异常有点误导,因为我并没有尝试修改Saxon节点)。所以我的问题是:什么是利用外部函数输入节点以返回它的修改版本的最佳方式(例如,添加一个额外的文本节点作为孩子)

提前致谢!

2 个答案:

答案 0 :(得分:1)

我的第一反应是在XSLT中操作XML节点树要比在Java中做得好得多,因此调用扩展函数以进行节点操作似乎很奇怪。特别是,"添加一个额外的文本节点作为孩子"是XSLT的设计目标,所以调用Java来实现它似乎很奇怪。

您用Java编写的用于操作节点的任何代码都将依赖于所使用的树模型。从错误消息中,听起来好像您可能最初使用Saxon的TinyTree模型构建树,然后将TinyTree节点包装在DOM包装器中以利用Java代码。 DOM包装器将为您提供用于检索/导航的DOM接口,但不提供更新,因为TinyTree是不可变的。

答案 1 :(得分:0)

不幸的是,以下代码失败了:

DOMWriter w = new DOMWriter(); 
w.setNode(programmaticallyCreatedNode); 
tinyTreeNode.copy(w, CopyOptions.ALL_NAMESPACES, 0);

with(我使用Saxon 9.1.0.8)

java.lang.NullPointerException
at net.sf.saxon.dom.DOMWriter.startElement(DOMWriter.java:103)
at net.sf.saxon.tinytree.TinyElementImpl.copy(TinyElementImpl.java:280)
...

我用以下内容复制了节点:

DOMWriter w = new DOMWriter();
w.setNode(parentElementProgramaticallyCreated);
Element toCopy = ...;
((ElementOverNodeInfo)toCopy).getUnderlyingNodeInfo().copy(w, NodeInfo.ALL_NAMESPACES, false, 0);

简要看一下代码,告诉我NPE是因为DOMWriter中没有初始化的namePool字段。也许我做错了什么,但我的直觉告诉我复制节点应该有点简单。

顺便说一句,我没有依赖于使用DOM与Saxon,任何允许我接收元素列表,从中读取基本信息的东西(我无法快速弄清楚如何获取属性列表使用来自TinyElementImpl的值和构造/复制节点将满足我的目的。同样,我在Java中使用属性值执行一些复杂的逻辑,并根据结果返回重新排列的XML树。在普通的XSLT中这样做真的很痛苦。