XPath从元素到元素选择祖先/后代树

时间:2013-01-27 01:53:31

标签: xml xslt xpath

我目前有一个xml文档,如下所示:

<site>
  <body>
    <group name="content">
      <Categories>
        <item id="1" name="cat1">
          <Children>
            <item id="2" name="cat2">
              <Children>
                <item id="3" name="cat3">
                  <Children>
                    <item id="4" name="cat4" />
                  </Children>
                </item>
                <item id="5" name="cat5">
                  <Children>
                    <item id="6" name="cat6" />
                    <item id="7" name="cat7" />
                    <item id="8" name="cat8" />
                  </Children>
                </item>
                <item id="9" name="cat9" />
                <item id="10" name="cat10" />
              </Children>
            </item>
          </Children>
        </item>
      </Categories>
    </group>
  </body>
</site>

如果用户选择了id = 3的类别:

我如何[在我的xsl样式表]中,从根类别元素中选择所有后代到所选元素,并迭代它们?也许是这样的:

<xsl:for-each select="//Categories//*[@id=3 and ancestor::Categories[1]]"> . .   ?

然后离开我:

<xsl:value-of select="@name" /> >

导致:

cat1 > cat2 > cat3 >

如果需要进一步说明,请与我们联系。

非常感谢。

1 个答案:

答案 0 :(得分:0)

此转化

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="item[@id=3]">
  <xsl:apply-templates mode="ancestors"
    select="ancestor-or-self::item"/>
 </xsl:template>

 <xsl:template match="item" mode="ancestors">
  <xsl:if test="not(position()=1)"> > </xsl:if>
  <xsl:value-of select="@name"/>
 </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档时:

<site>
  <body>
    <group name="content">
      <Categories>
        <item id="1" name="cat1">
          <Children>
            <item id="2" name="cat2">
              <Children>
                <item id="3" name="cat3">
                  <Children>
                    <item id="4" name="cat4" />
                  </Children>
                </item>
                <item id="5" name="cat5">
                  <Children>
                    <item id="6" name="cat6" />
                    <item id="7" name="cat7" />
                    <item id="8" name="cat8" />
                  </Children>
                </item>
                <item id="9" name="cat9" />
                <item id="10" name="cat10" />
              </Children>
            </item>
          </Children>
        </item>
      </Categories>
    </group>
  </body>
</site>

会产生想要的正确结果:

cat1 > cat2 > cat3

<强>更新

OP在评论中问道:

  

如何动态设置'id'值   match="item[@id=3]". .所以不要说一句话   <xsl:template match="item[@id=3]"> . .我可以说一句话   <xsl:template match="item[@id=$param]">

假设您有一个包含所需值的全局参数$pId

在XSLT 2.0中,只需修改xsl:template

 <xsl:template match="item[@id=3]">

 <xsl:template match="item[@id=$pId]">

在XSLT 1.0中,不允许在匹配模式中使用变量/参数引用。 下面是一个涵盖新要求的XSLT 1.0解决方案:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pId" select="3"/>

 <xsl:template match="item">
  <xsl:apply-templates mode="ancestors"
    select="self::*[@id=$pId]/ancestor-or-self::item"/>
  <xsl:apply-templates select="node()[not(current()/@id = $pId)]"/>
 </xsl:template>

 <xsl:template match="item" mode="ancestors">
  <xsl:if test="not(position()=1)"> > </xsl:if>
  <xsl:value-of select="@name"/>
 </xsl:template>
</xsl:stylesheet>