【问题标题】:get nth descendant node of given typefrom context node, they may not be siblings从上下文节点获取给定类型的第 n 个后代节点,它们可能不是兄弟节点
【发布时间】:2015-07-09 09:24:53
【问题描述】:

这与我不久前问过的question 有关。鉴于此 xml:

<?xml version="1.0"?>
<paper>
<section><title>My Main Section</title>
    <para>My para with a <footnote num="a">text</footnote> footnote.</para>
    <section><title>my subsection</title>
    <para>more text with another <empty/><footnote num="b">more fn text.    </footnote> footnote.</para>
    </section>
</section>
</paper>

我想要一个 xpath,来自 /paper/section 节点,它将只给我第一个脚注 (@num="a")

我已经尝试了一些类似的东西:

<xsl:template match="/paper/section">
    <section>
        <xsl:apply-templates select="//footnote[1]"/>
    </section>
</xsl:template>

但这会返回两个 fn。我假设因为每个 fn 都是其各自父节点中的第一个脚注节点。

我尝试了一些变化:

        <xsl:apply-templates select="//footnote[position() = 1 ]"/>

这将返回一个脚注,它是其父级的第一个子级,还是与1 相同?我所做的测试表明它们是相同的。

我也尝试了一个 for-each 循环,但无法拾取任何东西...

有什么想法吗? bp

【问题讨论】:

    标签: xslt xpath


    【解决方案1】:

    代替:

    select="//footnote[1]"
    

    尝试:

    select="descendant::footnote[1]"
    

    我一会儿再解释。


    其实我没有很好的解释;我只能引用XPath specification

    注意:位置路径//para[1] 与位置路径/descendant::para[1] 的含义不同。后者选择第一个 后代para元素;前者选择所有后代para 元素是他们父母的第一个 para 孩子。

    【讨论】:

      【解决方案2】:

      我已经尝试了一些类似的东西:

      <xsl:template match="/paper/section">
          <section>
              <xsl:apply-templates select="//footnote[1]"/>
          </section>
      </xsl:template>
      

      但这会返回两个 fn。

      这是一个常见问题解答。参见例如 this answer

      XPath [] 运算符的绑定比 // 伪运算符更强(具有更高的优先级)

      这就是为什么,

      //x[1]
      

      选择文档中的所有 x 元素,它们是其父元素的第一个 x 子元素。

      在 XPath 中,就像在数学中一样,要覆盖运算符的默认优先级,可以使用括号。

      使用

      (//x)[1]
      

      在这种特殊情况下,将 x 替换为特定的元素名称,我们得到了以下表达式:

      (//footnote)[1]
      

      如果需要文档的特定子树中的第一个 footnote 元素,请使用:

       (.//footnote)[1]
      

      用于评估表达式的上下文(当前)节点是子树的根


      解释

      // 实际上不是 XPath 运算符——它只是一个简写。引用W3C XPath 1.0 specification

      // 是/descendant-or-self::node()/的缩写

      这意味着

      //x[1]
      

      扩展为

      /descendant-or-self::node()/x[1]
      

      这会选择任何x 元素,它是作为根(文档)节点的后代的任何节点的第一个x 子节点。

      请注意上面的表达式非常不同与:

      /descendant::x[1]

      因此,这两个表达式选择的节点集通常是不同的。

      【讨论】:

      • 如果您想要本节中的第一个脚注而不是整个文档中的第一个脚注,则需要添加一个前导点:select="(.//footnote)[1]"(问题中的示例只有一个部分,但“我想要一个来自 /paper/section 节点的 xpath”的措辞表明实际情况有几个)
      【解决方案3】:

      使用descendant::para[x] 仍然会给我索引x 的所有项目,直到树的末尾(在Ranorex 8.1.2 上使用它)。

      但是通过应用descendant::para[x][n],我得到了沿着索引树X 向下的第N 个元素,或者甚至更好地使用descendant::para[][n] 来获得通过所有孩子及其孩子找到的第一个第N 个元素。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-05-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多