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

我是使用XPath的新手,这可能是一个基本的问题。请耐心等待,帮助我解决这个问题。我有一个这样的XML文件:

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

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

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

Now I also want to check the value of the tag for string "Data". For achieving this I was told to use:

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

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

断言失败消息:No Nodes Matched //Element[@attribute1="abc" and @attribute2="xyz" and Data]

请告诉我我使用的XPath表达式是否有效如果不是,有效的XPath表达式是什么?

299925 次浏览

条件如下:

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

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

你可以用

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

我添加这个答案的原因是我想解释.text()的关系。

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

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

在这种情况下,该值由函数boolean()计算为布尔值,并且有一个规则:

筛选器总是根据上下文进行计算。

当你需要将text().与字符串"Data"进行比较时,它首先使用string()函数将它们转换为字符串类型,然后它得到一个布尔结果。

关于string()有两个重要的规则:

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

    text()是一个相对路径,返回一个包含当前节点(上下文节点)的所有文本节点的节点集,如["Data"]。 当它被string(["Data"])求值时,它会返回节点集的第一个节点,所以你只会得到"Data"

    .当节点集中只有一个文本节点时
  2. 如果你想要string()函数连接整个子文本,你必须传递一个节点而不是一个节点集。

例如,我们得到一个节点集['a', 'b'],你可以将它们的父节点传递给string(parent),这将返回'ab',当然,在你的例子中,string(.)将返回一个连接的字符串"Data"

这两种方法都将导致相同的结果,但仅当存在文本节点时。