XPath:如何根据元素的值选择元素?


221

我是使用XPath的新手,这可能是一个基本问题。请多多包涵,并帮助我解决问题。我有一个像这样的XML文件:

<RootNode>
  <FirstChild>
    <Element attribute1="abc" attribute2="xyz">Data</Element>
  <FirstChild>
</RootNode>

我可以通过以下方式验证<Element>标签的存在:

// Element [@ attribute1 =“ abc”和@ attribute2 =“ xyz”]

现在,我还想检查一下string的标记值"Data"。为了达到这个目的,我被告知要使用:

// Element [@ attribute1 =“ abc”和@ attribute2 =“ xyz”和数据]

当我使用后面的表达式时,出现以下错误:

断言失败消息:没有匹配的节点 //Element[@attribute1="abc" and @attribute2="xyz" and Data]

请给我您的建议,我使用的XPath表达式是否有效。如果不是,什么是有效的XPath表达式?

Answers:


329

条件如下:

//Element[@attribute1="abc" and @attribute2="xyz" and Data]

检查元素中是否存在元素数据,而不是元素值数据。

相反,您可以使用

//Element[@attribute1="abc" and @attribute2="xyz" and text()="Data"]

25
//Element[@attribute1="abc" and @attribute2="xyz" and .="Data"]

为什么我添加此答案的原因是,我想解释的关系.text()

首先是使用时[],只有两种类型的数据:

  1. [number] 从节点集中选择一个节点
  2. [bool] 从节点集过滤节点集

在这种情况下,该值由function评估为布尔值boolean(),并且有一条规则:

始终根据上下文评估过滤器。

当您需要比较字符串text().与之比较时"Data",它首先使用string()函数将其转换为字符串类型,然后获得布尔结果。

关于以下两个重要规则string()

  1. string()函数通过返回节点集中第一个节点的字符串值,将节点集转换为字符串,这在某些情况下可能会产生意外的结果。

    text()是返回节点集的相对路径,该节点集包含当前节点(上下文节点)的所有文本节点,例如["Data"]。当使用进行评估时string(["Data"]),它将返回节点集的第一个节点,因此仅当该节点集中只有一个文本节点时,您才获得“数据”。

  2. 如果要让string()函数连接所有子文本,则必须传递单个节点而不是节点集。

    例如,我们得到一个节点集['a', 'b'],您可以将父节点传递到string(parent)该节点集,这将返回'ab',并且由于string(.)您的原因,将返回一个串联的字符串"Data"

仅当存在文本节点时,两种方式都将获得相同的结果。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.