【问题标题】:How to use XPath to filter elements by TextContent? get parent by axis?如何使用 XPath 按 TextContent 过滤元素?按轴获取父级?
【发布时间】:2011-03-02 11:16:32
【问题描述】:

我找到了a similar question on SO,但是,这似乎不是我想要实现的目标:

说,这是一个示例 XML 文件:

<root>
    <item>
        <id isInStock="true">10001</id>
        <category>Loose Balloon</category>
    </item>
    <item>
        <id isInStock="true">10001</id>
        <category>Bouquet Balloon</category>
    </item>
    <item>
        <id isInStock="true">10001</id>
        <category>Loose Balloon</category>
    </item>
</root>

如果我想从这个 XML 中获取项目元素的“过滤”子集,我如何使用 XPath 表达式直接解决这个问题?

XPathExpression expr = xpath.compile("/root/item/category/text()");

我现在知道这将评估为类别中所有 TextContent 的集合,但是,这意味着我必须使用集合来存储值,然后迭代,然后返回获取其他相关信息,例如再次输入项目 ID。

另一个问题是:如何正确引用父节点?

说,这个 xpath 表达式会让我得到所有 id 节点的集合,对吗?但我想要的是项目节点的集合:

XPathExpression expr = xpath.compile("/root/item/id[@isInStock='true']");

我知道我应该使用“父”轴来指代那个,但我就是无法正确...

有没有更好的方法来做这种事情?现在学习 w3cschools 教程...

抱歉,我是 Java 中 XPath 的新手,在此先感谢您。

【问题讨论】:

  • 好问题 (+1)。有关您需要的正确 XPath 表达式,请参阅我的答案。

标签: java xml xpath


【解决方案1】:

如果我想获得“过滤”的子集 此 XML 中的项目元素,如何 我可以使用 XPath 表达式 直接解决?

XPath 表达式示例:

/*/item[id/@isInStock='true']/category/text()

此 XPath 表达式选择所有 &lt;item&gt; 元素的所有 &lt;category&gt; 元素的所有文本节点子节点,其 isInStock 属性的 id 子节点的值为 'true' 和(id 元素)它们是 XML 文档顶部元素的子元素。

另一个问题是:我怎么能 正确引用父节点?

使用

parent::node()

或者干脆

..

【讨论】:

  • 感谢您的回答,我现在看到的表达式更像是一个查询。坦率地说,知道一个针对 xml(tree) 的查询/地址表达式非常有趣,类似于 jQuery 的,但不完全是:)
  • @Michael-Mao:我推荐的学习 XPath 的最佳方法是使用我自己的 XPath Visualizer。
  • 这个? xpathvisualizer.codeplex.com 相当不错,让我想起了 jQuery 选择器可视化工具 :)
  • 不,我的是 classic Xpath Visualizer(于 2000 年首次生产,位于 www.topxml.com。但是,该站点已被其维护者遗弃,现在包含木马(不要尝试访问它!)。如果有兴趣,请在谷歌电子邮件域的 dnovatchev 询问我,我会发送给您。
【解决方案2】:

Java。

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Node;

以下 XPath 表达式可用于按文本内容过滤元素。

**String xPathString = "/root/item/category[text()='Bouquet Balloon']";** 

XPath xPath = XPathFactory.newInstance().newXPath();     
XPathExpression xPathExpression = xPath.compile(xPathString);

将结果评估为所需的类型,

Object result = xPathExpression.evaluate(getDrugBankXMLDoc(), XPathConstants.NODE);

获取选中节点的父节点(import org.w3c.dom.Node;),

Node baloon = (Node)result;
if (baloon != null)
{
     baloon = baloon.getParentNode();
}

【讨论】:

    【解决方案3】:

    要选择item,可以继续谓词后面的路径跳回到找到的id(s)的父级

    XPathExpression expr = xpath.compile("/root/item/id[@isInStock='true']/../text()");
    

    当您对此进行评估时,它应该返回一个包含过滤后的 item 节点(及其子树)的 NodeList,然后您可以对其进行迭代。

    【讨论】:

    • 啊哈,这是我自己没有尝试过的唯一情况......感谢您的回答
    • 糟糕——我刚刚在您回复时编辑了我的原始答案。实际上,我的第一个反应是不正确的(我试过了)。现在有什么效果。
    • 感谢您。我对 XPath 完全陌生,所以我总是遇到错误 :) 现在我更清楚地看到了表达式背后的逻辑。
    猜你喜欢
    • 1970-01-01
    • 2016-10-14
    • 2011-10-20
    • 2019-05-21
    • 2016-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多