Saxon XPath API 返回 TinyElementImpl 而不是 org.w3c.dom.Node
我有以下代码:
// xpath evaluates to net.sf.saxon.xpath.XPathEvaluator
XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression expression = xpath.compile("/foo/bar");
Object evaluate = expression.evaluate(someXML, XPathConstants.NODE);
Object evaluate2 = expression.evaluate(someXML, XPathConstants.NODESET);
System.out.println(evaluate!=null?evaluate.getClass():"null");
System.out.println(evaluate2!=null?evaluate2.getClass():"null2");
System.out.println(evaluate instanceof Node);
System.out.println(evaluate2 instanceof NodeList);
这就是结果...
class net.sf.saxon.tinytree.TinyElementImpl class java.util.ArrayList false false
只是为了澄清,如果我这样做:
org.w3c.dom.Node node = (org.w3c.dom.Node)evaluate;
或者
org.w3c.dom.NodeList node = (org.w3c.dom.NodeList)evaluate2;
我得到一个 ClassCastException
那怎么可能?根据 Suns Java 1.5 API< /a> NODE 和 NODESET 应分别映射到 org.w3c.dom.Node
和 org.w3c.dom.NodeList
只是为了澄清 是我知道 Node 是一个 iterface, getClass() 返回一个具体的类。
I have the following code:
// xpath evaluates to net.sf.saxon.xpath.XPathEvaluator
XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression expression = xpath.compile("/foo/bar");
Object evaluate = expression.evaluate(someXML, XPathConstants.NODE);
Object evaluate2 = expression.evaluate(someXML, XPathConstants.NODESET);
System.out.println(evaluate!=null?evaluate.getClass():"null");
System.out.println(evaluate2!=null?evaluate2.getClass():"null2");
System.out.println(evaluate instanceof Node);
System.out.println(evaluate2 instanceof NodeList);
and this is the result...
class net.sf.saxon.tinytree.TinyElementImpl class java.util.ArrayList false false
Just to clarify, if I do this:
org.w3c.dom.Node node = (org.w3c.dom.Node)evaluate;
or
org.w3c.dom.NodeList node = (org.w3c.dom.NodeList)evaluate2;
I get a ClassCastException
How can that be? according to Suns Java 1.5 API NODE and NODESET should map to org.w3c.dom.Node
and org.w3c.dom.NodeList
respectively
Just to clarify2 yes I know Node is an iterface, that getClass() returns a concrete class.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
好吧,我想通了!
如果评估方法接收到一个InputSource,则会发生上述错误。
例如,
那么结果没有实现
org.w3c.dom.Node
(TinyElementImpl
)但如果评估接收到
Node
(或Document
):它有效,但是,这仍然很奇怪......
Ok I figured it out!
If the evaluate method receives an InputSource the above error occurs.
e.g.
Then result is not implementing
org.w3c.dom.Node
(TinyElementImpl
)But if evaluate receives a
Node
(or aDocument
):It works, but still, this is weird...
试试这个代码:
它打印:
返回的对象是
NodeInfo
类型,所以你需要将它包装为一个真正的Node
,这样你就可以访问它的方法:Try this code:
It prints:
The returned object is of type
NodeInfo
, so you need wrap it as a realNode
, so you can access its methods:有点奇怪,这个。 Saxon javadoc 说
TinyElementImpl
不实现任何org.w3c.dom
接口,但您可以从 XPath 评估中获取它们。我的猜测是 Saxon 避开了标准 DOM 模型而选择了自己的模型。我怀疑您传递给
evaluate
的XPathConstants.NODE
实际上只是一个提示。允许 XPath 表达式返回任何旧的内容(例如,Apache JXPath 使用 XPath 表达式来查询java 对象图),因此 Saxon 可以返回自己的 DOM 类型,而不是org.w3c
标准类型。解决方案:要么使用返回的 Saxon DOM 类型,要么不使用 Saxon。
It's a bit odd, this one. The Saxon javadoc says that
TinyElementImpl
doesn't implement any of theorg.w3c.dom
interfaces, and yet you're getting them back from the XPath evaluation.My guess is that Saxon eschews the standard DOM model in favour of its own one. I suspect that the
XPathConstants.NODE
that you pass toevaluate
is really just a hint. It's permitted for XPath expressions to return any old thing (for example, Apache JXPath uses XPath expressions to query java objects graphs), so it's permitted for Saxon to return its own DOM types rather thanorg.w3c
standard ones.Solution: either use the Saxon DOM types as returned, or don't use Saxon.
Node
是一个接口。你必须有一个具体的类来实现。 getClass() 返回该具体类。编辑回应评论:
抱歉,我没有注意instanceof。查看 源代码,看来
TinyNodeImpl
没有实现org.w3c.dom.Node
。查看 JDK 文档,似乎不必这样做: javax.xml.XPath 指的是 XPathConstants 用于结果类型,它引用“XPath 1.0 NodeSet 数据类型”(如果您查看 XPath 1.0 规范,则未定义该类型) )。因此,似乎 XPath API 的返回值只需要在该 API 中使用时保持一致。我确信这不完全是你想听到的。可以使用内置的JDK实现吗?我知道它返回 org.w3c.dom 对象。
Node
is an interface. You have to have a concrete class for implementation. AndgetClass()
returns that concrete class.Edit in response to comment:
Sorry, I didn't pay attention to the instanceof. Looking at the source code, it appears that
TinyNodeImpl
doesn't implementorg.w3c.dom.Node
. And looking at the JDK docs, it appears that it doesn't have to: the doc for javax.xml.XPath refers you to XPathConstants for the result type, and it refers to the "The XPath 1.0 NodeSet data type" (which, if you look at the XPath 1.0 spec, is not defined).So, it seems that returns from the XPath API are only required to be consistent when used within that API. Not exactly what you wanted to hear, I'm sure. Can you use the built-in JDK implementation? I know that it returns
org.w3c.dom
objects.kdgregory 是正确的,
Node
只是一个接口,而TinyElementImpl
实现了该接口。expression.evaluate()
无法返回Node
的实例,它必须返回一个实现节点的具体类。指出您可以使用
TinyElementImpl
as 的实例作为Node
可能会很有用,并且您可以轻松地转换的实例TinyElementImp
到Node
。例如,这应该可以正常工作:
然后您可以通过调用
Node
的任何方法并将其传递给任何接受的方法来使用
。result
节点kdgregory is correct that
Node
is just an interface, andTinyElementImpl
implements that interface.expression.evaluate()
can't return an instance ofNode
, it has to return a concrete class which implements node.It might be useful to point out that you can use an instance of
TinyElementImpl
as asNode
, and you can easily cast instances ofTinyElementImp
toNode
.For example, this should work just fine:
You can then use
result
by calling any of the methods ofNode
, and by passing it to any method which accepts aNode
.