Java 在子节点上运行 XPath

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2618136/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 09:56:58  来源:igfitidea点击:

Running XPath on child node

javaxpath

提问by Jeeyoung Kim

I'm trying to do a xpath lookup on nodes returned by xpath lookup, but it doesn't seem to work as I expected.XPaths executed on the child nodes of a document seem to be executd against hthe root node of the document (in the example, the inventory tag.), instead of the root of the provided node.

我正在尝试对 xpath 查找返回的节点进行 xpath 查找,但它似乎没有按我预期的那样工作。在文档的子节点上执行的 XPaths 似乎是针对文档的根节点执行的(在例如,库存标签。),而不是提供的节点的根。

Am I missing something here? I'm new to XPath.

我在这里错过了什么吗?我是 XPath 的新手。

Also, please don't answer "just do //book[author='Neal Stephenson'/title". I have a legitimate use case, and this is a simplified example.

另外,请不要回答“只是做 //book[author='Neal Stephenson'/title”。我有一个合法的用例,这是一个简化的例子。

Code snippet

代码片段

DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse("src/main/java/books.xml");

XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();

Node book = (Node) xpath.evaluate("//book[author='Neal Stephenson']", doc, XPathConstants.NODE);
Node title = (Node) xpath.evaluate("/title", book, XPathConstants.NODE); // I get null here.
Node inventory = (Node) xpath.evaluate("/inventory", book, XPathConstants.NODE); // this returns a node.

book.xml

书本.xml

<inventory>
<book year="2000">
    <title>Snow Crash</title>
    <author>Neal Stephenson</author>
    <publisher>Spectra</publisher>
    <isbn>0553380958</isbn>
    <price>14.95</price>
</book>

<book year="2005">
    <title>Burning Tower</title>
    <author>Larry Niven</author>
    <author>Jerry Pournelle</author>
    <publisher>Pocket</publisher>
    <isbn>0743416910</isbn>
    <price>5.99</price>
</book>

<book year="1995">
    <title>Zodiac</title>
    <author>Neal Stephenson</author>
    <publisher>Spectra</publisher>
    <isbn>0553573862</isbn>
    <price>7.50</price>
</book>

<!-- more books... -->

</inventory>

采纳答案by Pete Hodgson

/foowill select based off of the root node, ignoring the context that you are evaluating the xpath against. foo(without the slash) is what you want; that selects based off of the current node.

/foo将根据根节点进行选择,忽略您正在评估 xpath 的上下文。foo(没有斜线)就是你想要的;基于当前节点进行选择。

https://www.w3schools.com/xml/xpath_syntax.aspgives a bit more info.

https://www.w3schools.com/xml/xpath_syntax.asp提供了更多信息。

回答by Corey Porter

Just take the leading slash off of your subqueries and you should be fine. So you get your books via "//book", and then from there it's just "title", "inventory"etc to get the child bits.

只需去掉子查询的前导斜杠,你应该没问题。所以你通过 得到你的书"//book",然后从那里它只是"title""inventory"等等来获取孩子的位。

回答by mauhiz

What is actually weird in the Java implementation is that a Node extracted from a Document still references the parent Document (see Node.getOwnerDocument()) and xpath uses this to find the root.

Java 实现中真正奇怪的是,从 Document 提取的 Node 仍然引用父 Document(请参阅 参考资料Node.getOwnerDocument()),而 xpath 使用它来查找根。

Others have mentioned a way to modify the xpath to actually notstart from the root by removing the slashes.

其他人提到了一种通过删除斜杠来修改 xpath 以使其实际上不是从根开始的方法。

I had a similar issue but I wanted the xpath to handle both root documents and child nodes (with an xpath like /title). The solution was to clonethe node : Node.cloneNode(true). Note the trueparameter that makes the Node shake its parent Document off.

我有一个类似的问题,但我希望 xpath 处理根文档和子节点(使用类似 的 xpath /title)。解决方案是克隆节点:Node.cloneNode(true)。请注意true使 Node 摆脱其父 Document的参数。

...In the end, it hurts performance too much and having separate xpaths to handle Node and Document was preferred.

...最后,它对性能的影响太大了,最好使用单独的 xpath 来处理 Node 和 Document。

回答by Salman

in Xpath, "." (Dot) represents the current document. So, write your XPATH string after a "." (Dot) .

在 Xpath 中,“.” (点)代表当前文档。因此,在“.”之后写入 XPATH 字符串。(点)。

ex :

前任 :

"./title"

or

或者

".//title"

Whatever you want....

任何你想要的....

removing the slash works only if its a child of the node. What if you want to use the // (wherever in the current Document) functionality ?

删除斜杠仅在它是节点的子节点时才有效。如果您想使用 //(在当前文档中的任何位置)功能怎么办?

So, use the dot (.)

因此,请使用点 (.)

Thanks a lot for the above answers too :) .

也非常感谢上述答案:)。