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
Running XPath on child node
提问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
/foo
will 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.
回答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 true
parameter 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 :) .
也非常感谢上述答案:)。