XPath 仅在节点存在时才获取兄弟姐妹计数

XPath get the siblings count only if node is present

我有一个 XML,它将包含 table 信息(header 列和行)。

<Table> 
      <colHeading>name</colHeading>
      <colHeading>phoneNumber</colHeading>
      <colHeading>email</colHeading>
      <row>
          <col>jack</col>   
          <col>9123456352</col>
          <col>asd@abc.com</col>
      </row>
</Table>

我需要从 XML 中识别 phoneNumber 值。 order/column 名称是动态的,因此硬编码索引值将不起作用。即,首先获取值为 "phoneNumber" 的 columHeading 索引,然后选择 row/col[index] 值。为此,我编写了一个工作正常的 Xpath 表达式,如果有 phoneNumber 列,则 return 正确的值。

.//row/col[count(//colHeading[text() = 'phoneNumbr']/preceding-sibling::*)+1]/text()

我面临的问题是,当没有 phoneNumber 列时,它将始终 return 第一个 row/col 值,因为我将 +1 添加到 preceding-sibling 值。

如何在 xpath 中处理这种情况。也就是说,如果 "phoneNumber" 存在,那么只有我应该识别兄弟姐妹并加 1。否则它应该 return 0 作为索引。 xpath 中是否有任何函数可用于处理这种情况。我正在使用 XPATH1.0.

您可以检查布尔表达式 ../../colHeading='phoneNumbr' 以查看该列是否存在,然后使用类型转换规则 - 将布尔值转换为数字给出 0 表示假,1 表示真。

.//row/col[count(../../colHeading[.='phoneNumbr']/preceding-sibling::*)
       + boolean(../../colHeading = 'phoneNumbr')]/text()

当没有 phoneNumbr 列时,这将 return 一个空节点集。

在谓词中使用 text() 绝对是多余的,最后的那个可能会也可能不会完全取决于您对结果节点集所做的事情。

一种可能的 hack 方法是从 <phoneNumber> 的下一个兄弟开始计算前一个兄弟。这样你就不需要添加 +1 :

//row/col[
       count(../../colHeading[. = 'phoneNumber']/following-sibling::*[1]/preceding-sibling::*)
    ]/text()

令人惊讶的是, 这甚至适用于 <phoneNumber> 没有以下兄弟姐妹的情况,例如:

<Table> 
      <colHeading>name</colHeading>
      <colHeading>phoneNumber</colHeading>
      <row>
          <col>jack</col>   
          <col>9123456352</col>
      </row>
</Table>

您不需要将 return 0 作为索引,只需在 row 选择上添加谓词 [preceding-sibling::colHeading = 'phoneNumber']

示例:

.//row
[
    preceding-sibling::colHeading = 'phoneNumber'
]
/col
[
    count(../../colHeading[. = 'phoneNumber']/preceding-sibling::*)+1
]
/text()