2009-02-11 61 views
3

我了解如何使用XSLT从最外面的元素处理此文档(下面)到最里面。但我想知道是否:XSLT - 递归式向外工作

  1. 如果它有可能从最深的元素出来。
  2. 这看起来像给我的例子。
<?xml version="1.0" encoding="utf-8" ?> 
<container> 
    <person name="Larry"> 
    <person name="Moe"> 
     <person name="Curly"> 
     <person name="Shemp"> 

     </person> 
     </person> 
    </person> 
    </person> 
</container> 
+0

@Bruno Tyndall我已经用.NET 2.0 + XslCompiledTransform测试了这个转换。它应该也适用于较旧的XslTransform。 – 2009-02-12 03:30:19

回答

2

以下是执行“向后递归”的最一般方法,它不依赖于此特定问题并可用于各种各样的问题。

这种转变

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

    <xsl:template match="/"> 
     <xsl:call-template name="backwardsRecursion"> 
     <xsl:with-param name="pList" select="//person"/> 
     </xsl:call-template> 
    </xsl:template> 

    <xsl:template name="backwardsRecursion"> 
     <xsl:param name="pList"/> 

     <xsl:if test="$pList"> 
     <xsl:apply-templates select="$pList[last()]"/> 

     <xsl:call-template name="backwardsRecursion"> 
      <xsl:with-param name="pList" select= 
      "$pList[position() &lt; last()]"/> 
     </xsl:call-template> 
     </xsl:if> 
    </xsl:template> 

    <xsl:template match="person"> 
     <xsl:value-of select="concat(@name,'&#xA;')"/> 
    </xsl:template> 
</xsl:stylesheet> 

当在最初提供的XML文档应用时产生通缉的结果

Shemp 
Curly 
Moe 
Larry 

请注意,一个通用模板命名“backwardsRecursion”被调用,真正实现了向后递归。 该模板不知道任何关于它处理的节点,或者它们将如何处理

因此,该模板可用于需要向后递归处理的每种情况。

11

您可以使用父::轴的工作了。

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="/"> 
     <xsl:apply-templates select="//person[not(person)]"/> 
    </xsl:template> 
    <xsl:template match="person"> 
    <xsl:value-of select="@name"/> -&gt; <xsl:apply-templates select="parent::person"/> 
    </xsl:template> 
</xsl:stylesheet> 

未经测试,我可能是关闭语法。

应该打印Shemp - >卷毛 - >萌 - >拉里

+0

+1似乎很好地工作。 – 2009-02-11 14:30:44

+0

对于“// person [not(person)]”来说值得+1。 :-) – 2009-02-12 00:21:13

1

类似于师德的解决方案,但让“人”的要素是在没有直接父子关系如下:

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

    <xsl:template match="/"> 
     <xsl:apply-templates select="//person[not(person)]"/> 
    </xsl:template> 

    <xsl:template match="person" name="tPerson"> 
     <xsl:value-of select="concat(@name,'&#xA;')"/> 

     <xsl:apply-templates select= 
      "ancestor::person[1]"/> 
    </xsl:template> 
</xsl:stylesheet> 

当在最初提供的XML文档施加时,正确的结果产生

Shemp

卷毛

拉里

这是好事,知道这种类型的许多问题并不需要递归了! 这种转变产生完全相同的结果,只是涉及迭代

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

    <xsl:template match="/"> 
     <xsl:for-each select="//person[not(person)]"> 
      <xsl:for-each select="ancestor::person | ."> 
      <xsl:sort select="position()" order="descending"/> 
       <xsl:value-of select="concat(@name,'&#xA;')"/> 
      </xsl:for-each> 
     </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 

请注意,确保处理的相反顺序排序