只有节点存在时,XPath才会获取兄弟节点数

时间:2015-03-27 07:48:33

标签: xml xpath

我有一个XML,它将包含表信息(列标题和行)。

<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值。 订单/列名称是动态的,因此硬编码索引值将不起作用。即,首先获取columHeading索引,其中value是“phoneNumber”并选择row / col [index]值。为此,我写了一个Xpath表达式,它正常工作,如果有phoneNumber列,则返回正确的值。

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

我面临的问题是,当没有phoneNumber列时,它将始终返回第一行/ col值,因为我正在向前一个兄弟值添加+1。

如何在xpath中处理这种情况。即如果“phoneNumber”存在,那么只有我应该识别兄弟姐妹并添加1.另外,它应该返回0作为索引。在xpath中是否有任何可用于处理此场景的函数。我正在使用XPATH1.0。

3 个答案:

答案 0 :(得分:1)

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

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

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

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

答案 1 :(得分:1)

实现这一点的一个可能的 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>

答案 2 :(得分:1)

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

实施例

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