首页 文章

使用xpath查找父节点的位置

提问于
浏览
9

如何使用xpath获取完整文档中父节点的位置?

说我有以下xml:

<catalog>
  <cd>
    <title>Empire Burlesque</title>
    <artist>Bob Dylan</artist>
    <country>USA</country>
    <company>Columbia</company>
    <price>10.90</price>
    <year>1985</year>
  </cd>
  <cd>
    <title>Hide your heart</title>
    <artist>Bonnie Tyler</artist>
    <country>UK</country>
    <company>CBS Records</company>
    <price>9.90</price>
    <year>1988</year>
  </cd>
</catalog>

我有一个XSLT将其转换为HTML,如下所示(仅限片段):

<xsl:template match="/">
<html>
  <body>  
  <xsl:apply-templates/>  
  </body>
  </html>
</xsl:template>

<xsl:template match="cd">
  <p>
    <xsl:number format="1. "/>
<xsl:apply-templates select="title"/> <xsl:apply-templates select="artist"/> </p> </xsl:template> <xsl:template match="title"> <xsl:number format="1" select="????" />
Title: <span style="color:#ff0000"> <xsl:value-of select="."/></span>
</xsl:template>

我该怎么写在????的地方?获取文档中父CD标记的位置 . 我尝试过很多表达式,但似乎没有任何效果 . 可能是我完全错了 .

  • <xsl:number format="1" select="catalog/cd/preceding-sibling::..[position()]" />

  • <xsl:number format="1" select="./parent::..[position()]" />

  • <xsl:value-of select="count(cd/preceding-sibling::*)+1" />

我将第二个解释为选择当前节点的父轴,然后告诉当前节点的父节点的位置 . 为什么不起作用?这样做的正确方法是什么 .

仅供参考:我希望代码能够打印当前 Headers 标签uder处理的父CD标签的位置 .

请有人告诉我如何做到这一点 .

3 回答

  • 18
    count(../preceding-sibling::cd) + 1
    

    你可以run it here(注意我删除了你输出的另一个号码,只是为了清晰起见) .

    你是在正确的行,但请记住,谓词只用于过滤节点,而不是返回信息 . 所以:

    ../*[position()]
    

    ...有效地说“找到有我职位的父母” . 它返回节点,而不是位置本身 . 谓词只是一个过滤器 .

    在任何情况下,使用 position() 都存在缺陷,它可用于返回当前上下文节点 only 的位置 - 而不是另一个节点 .

  • 1

    Utkanos的答案很好但我的经验是,当xml文档很大时,这可能会导致性能问题 .

    在这种情况下,您可以简单地在父级中传递父级的位置 .

    <xsl:template match="/">
    <html>
      <body>  
      <xsl:apply-templates/>  
      </body>
      </html>
    </xsl:template>
    
    <xsl:template match="cd">
      <p>
        <xsl:number format="1. "/>
    <xsl:apply-templates select="title"> <xsl:with-param name="parent_position" select="position()"/> <!-- Send here --> </xsl:apply-templates> <xsl:apply-templates select="artist"/> </p> </xsl:template> <xsl:template match="title"> <xsl:param name="parent_position"/> <!-- Receive here --> <xsl:number format="1" select="$parent_position"/>
    Title: <span style="color:#ff0000"> <xsl:value-of select="."/></span>
    </xsl:template>

    结果:

    <html xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><body>
      <p>1. <br>1<br>
      Title: <span style="color:#ff0000">Empire Burlesque</span><br>Bob Dylan</p>
      <p>2. <br>1<br>
      Title: <span style="color:#ff0000">Hide your heart</span><br>Bonnie Tyler</p>
    </body></html>
    
  • 4

    <xsl:数字格式=“1”select =“????” />
    我该怎么写在????的地方?获取文档中父CD标记的位置 .

    First of all, the above XSLT instruction is syntactically illegal -- the xsl:number instruction doesn't (cannot) have a select attribute .

    Use

    <xsl:number format="1" count="cd" />
    

相关问题