2010-04-07 21 views
8

我有一个情况遍历一个排序节点集和应用在每个节点的模板:传递给XSL之前排序节点集:对,每个

<div id="contractscontainer"> 
    <xsl:for-each select="document"> 
    <xsl:sort select="content[@name='ClientName']/text()" /> 
    <xsl:apply-templates select="." mode="client-contract" /> 
    </xsl:for-each> 
</div> 

我想要做一些特别的“第一个“节点集中的5个节点并呈现它们的嵌套元素。问题是他们需要按照相同的顺序进行排序(因为他们在循环中)。

我已经计划通过使用两个xsl:for-each元素来完成此操作,每个元素都具有从集合中选择的正确节点。我不能做到这一点,但是,因为它们需要进行排序之前我可以选择“第一” 5.

例子:

<div id="contractscontainer"> 
    <div class="first-five"> 
    <xsl:for-each select="document[position() < 6]"> 
     <xsl:sort select="content[@name='ClientName']/text()" /> 
     <xsl:apply-templates select="." mode="client-contract" /> 
    </xsl:for-each> 
    </div> 
    <div class="rest-of-them"> 
    <xsl:for-each select="document[position() > 5]"> 
     <xsl:sort select="content[@name='ClientName']/text()" /> 
     <xsl:apply-templates select="." mode="client-contract" /> 
    </xsl:for-each> 
    </div> 
</div> 

我不认为这会工作,因为我在排序前选择位置,但我不能在xsl:for-each以外使用xsl:sort

我接近这个不正确吗?

编辑:我目前的解决方案是对它们进行排序和存储排序另一个变量设置:

<xsl:variable name="sorted-docs"> 
    <xsl:for-each select="document"> 
    <xsl:sort select="content[@name='ClientName']/text()" /> 
    <xsl:copy-of select="." /> 
    </xsl:for-each> 
</xsl:variable> 

它的工作原理,但有没有更好的办法?

+0

好问题(+1)。您当前的解决方案并不错,但带有排序元素的xsl:variable属于RTF类型,您需要在XSLT 1.0中使用xxx:node-set()扩展函数。看到我的解决方案如何做到这一点,而不需要任何扩展功能。 – 2010-04-07 22:18:09

+0

是的,我结束了这样做:使用exsl:node-set()。感谢您的解决方案! – 2010-04-07 22:42:50

回答

14

这里是为此在XSLT 1.0,而无需使用xxx:node-set()扩展功能一个办法:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="/*"> 
    <html> 
    <div class="first-five"> 
    <xsl:apply-templates select="num"> 
     <xsl:sort select="." data-type="number"/> 
     <xsl:with-param name="pStart" select="1"/> 
     <xsl:with-param name="pEnd" select="5"/> 
    </xsl:apply-templates> 
    </div> 
    <div class="rest-of-them"> 
    <xsl:apply-templates select="num"> 
     <xsl:sort select="." data-type="number"/> 
     <xsl:with-param name="pStart" select="6"/> 
    </xsl:apply-templates> 
    </div> 
    </html> 
</xsl:template> 

<xsl:template match="num"> 
    <xsl:param name="pStart"/> 
    <xsl:param name="pEnd" select="999999999999"/> 

    <xsl:if test="position() >= $pStart 
       and 
       not(position() > $pEnd)"> 
    <p><xsl:value-of select="."/></p> 
    </xsl:if> 
</xsl:template> 

</xsl:stylesheet> 

当上述转变被这个简单的XML文档施加:

<nums> 
    <num>5</num> 
    <num>3</num> 
    <num>6</num> 
    <num>8</num> 
    <num>4</num> 
    <num>1</num> 
    <num>9</num> 
    <num>2</num> 
    <num>7</num> 
    <num>10</num> 
</nums> 

想要的结果产生

<html> 
    <div class="first-five"> 
     <p>1</p> 
     <p>2</p> 
     <p>3</p> 
     <p>4</p> 
     <p>5</p> 
    </div> 
    <div class="rest-of-them"> 
     <p>6</p> 
     <p>7</p> 
     <p>8</p> 
     <p>9</p> 
     <p>10</p> 
    </div> 
</html> 
+0

解决了我的问题,谢谢 – 2010-05-20 23:30:17