首页 文章

在子节点上运行XPath

提问于
浏览
46

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

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

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

代码段

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

<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>

4 回答

  • 3

    只需从你的子查询中删除主要的斜线就可以了 . 所以你通过 "//book" 得到了你的书,然后从那里得到了孩子的位,只有 "title""inventory" 等 .

  • 7

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

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

  • 24

    在Xpath中,“ . ” (点)代表当前文档 . 所以,在“ . ”之后写下你的XPATH字符串 . (点) .

    例如:

    "./title"
    

    要么

    ".//title"
    

    任何你想要的....

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

    所以,使用点( . )

    非常感谢上面的答案:) .

  • 45

    Java实现中实际上奇怪的是,从Document中提取的节点仍引用父Document(请参阅 Node.getOwnerDocument() ),xpath使用它来查找根 .

    其他人已经提到了一种方法来修改xpath,实际上不是通过删除斜杠从根开始 .

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

    ...最后,它会对性能造成太大影响,并且需要使用单独的xpath来处理Node和Document .

相关问题