我应该使用哪一个:前置:: 或前置兄弟::?

tar*_*ara 4 xml xslt xpath

我正在犹豫是否要编写precedingpreceding-sibling使用 XSL,例如下面的示例 xml。

<sales_division>
  <team area="Tokyo">
    <staff>Sato</staff>
    <staff>Tanaka</staff>
  </team>
  <team area="Osaka">
    <staff>Ueda</staff>
    <staff>Suzuki</staff>
  </team>
</sales_division>
Run Code Online (Sandbox Code Playgroud)

如果当前节点是,并且我想获取的team(@Osaka)第一个子节点,我应该如何正确编写 Xpath ?staff(Sato)team(@Tokyo)

我猜想以下三个选项。

1) preceding-sibling::team/staff[1]<br>
2) preceding::staff[2]<br>
3) ../team[1]/staff[1]
Run Code Online (Sandbox Code Playgroud)

请给我你的建议和意见。

Abe*_*bel 6

在我看来,您(也)在问这些轴实际上是做什么的。正如迈克尔和哈尔已经指出的那样,是否选择其中之一实际上取决于大局。在实践中,对 、 和 的需求preceding在较小程度上preceding-sibling可能是代码异味的标志,并且它们的性能可能是有害的,具体取决于输入和谓词。

假设您的输入略有不同:

<sales_division>
  <team area="New York">
    <staff>John</staff>
  </team>
  <team area="Tokyo">
    <staff>Sato</staff>
    <staff>Tanaka</staff>
  </team>
  <staff />
  <team area="Osaka">
    <staff>Ueda</staff>
    <staff>Suzuki</staff>
  </team>
</sales_division>
Run Code Online (Sandbox Code Playgroud)

1) 前辈兄弟姐妹::团队/员工[1]

前同级轴是反向轴,这意味着它从下到上穿过您的同级轴。这staff一步实际上是child::staff,这本身就是向前迈出的一步。

在这里你要问的是:

  • 获取所有前面匹配的兄弟姐妹team
  • 在所有这些中,向下选择第一个staff
  • 在增强的 XML 中,这将选择“John”

2) 前面的::工作人员[2]

前面的轴也是反向轴,但它不是遍历兄弟节点,而是遍历所有已经经过的节点(意思是:如果一个节点仍在当前祖先轴中,则不被选择),深度优先(含义:文本节点位于子节点staff之前staff,子节点位于team兄弟节点之前)。

在这里你要问的是:

  • 取所有匹配 的前面节点staff,即空,Tanaka、Sato 和 John(按顺序)。
  • 选择您找到的第二个
  • 在增强的 XML 中,这将选择 Tanaka

3) ../团队[1]/员工[1]

..是 的缩写parent::node()。这意味着获取当前节点的父节点(即根元素sales_division

在这里你要问的是:

  • 去找父母sales_division
  • 从那里向下找到第一个匹配的子项team
  • 从那里找到第一个匹配的子项staff
  • 在增强的 XML 中,这是 John

因此,总而言之,这取决于实际的 XML 结构。典型的用例preceding-sibling是 XML 的顺序已知且有意义(例如,两个坐标,其中前一个同级是经度,当前是纬度)。

在实践中,我更经常看到您需要一个在当前节点之前之后的同级元素。在这种情况下,..(父)语法可能是最好的方法,可能会从节点集中排除当前节点。这在 XSLT 2.0 和 3.0 中比在 1.0 中更容易。