【问题标题】:XPath get the siblings count only if node is present仅当节点存在时,XPath 才获取兄弟姐妹计数
【发布时间】:2015-03-27 07:48:32
【问题描述】:

我有一个包含表格信息(列标题和行)的 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 值。 订单/列名是动态的,因此硬编码的索引值将不起作用。即,首先获取值为“phoneNumber”的columHeading 索引,然后选择row/col[index] 值。为此,我编写了一个工作正常的 Xpath 表达式,如果有 phoneNumber 列,则返回正确的值。

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

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

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

【问题讨论】:

  • 这样如果 phoneNumber 不存在 row/col[0] 将不会返回任何值

标签: xml xpath


【解决方案1】:

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

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

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

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

【讨论】:

  • 我试过这个但不工作..condition boolean(../colHeading='phoneNumber') 将始终返回 false...我也不确定 '+' 如何在布尔值上工作
  • @Andromeda 抱歉,路径错误,需要另一个 ../。您可以像原来一样在谓词中使用 //,但我倾向于尽可能本地化我的路径,即查看 this table 中的 col 标题,而不是文档中的任何地方(在这种情况下,它们都是相同的,但为了提高效率,最好尽可能远离//)。
  • @Andromeda 和 + 运算符自动将其参数转换为数字,因此 x + boolean 将是 x 为 false 和 x+1 为 true。
【解决方案2】:

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

示例:

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

【讨论】:

    【解决方案3】:

    一个可能的hack 是通过从&lt;phoneNumber&gt; 的下一个兄弟开始计算前一个兄弟。这样就不用加+1了:

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

    令人惊讶的是, 这甚至适用于&lt;phoneNumber&gt; 没有跟随兄弟的情况,例如:

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

    【讨论】:

    • 不出所料......在这种情况下,标签行是“colHeading”的兄弟......并且从那里前兄弟会给出确切的计数:-)
    • @Andromeda 你说得对,只是过于关注cols 和colHeadings 也许:D
    猜你喜欢
    • 2012-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多