2014-06-26 31 views
1

我想对我的xml文件进行两个不同的字段排序: 标识符和影响。 我想通过标识符排列元素,除了必须出现最后一个XX产品的元素外。xslt在两个不同的字段中进行双重排序

我的XML文件是

<evolutionlist> 
<date> 
    <object> 
     <identifier>id5</identifier> 
     <impact> 
      <product>AA</produit> 
     </impact> 
    </objet> 
    <object> 
     <identifier>id2</identifier> 
     <impact> 
      <product>XX</produit> 
     </impact> 
    </objet> 
    <object> 
     <identifier>id4</identifier> 
     <impact> 
      <product>BB</produit> 
     </impact> 
    </objet> 
    <object> 
     <identifier>id3</identifier> 
     <impact> 
      <product>XX</produit> 
     </impact> 
    </objet> 
    <object> 
     <identifier>id1</identifier> 
     <impact> 
      <product>CC</produit> 
     </impact> 
    </objet> 
</date> 
</evolutionlist> 

的expceted结果将是:

<evolutionlist> 
<date> 
    <object> 
     <identifier>id1</identifier> 
     <impact> 
      <product>CC</produit> 
     </impact> 
    </objet> 
    <object> 
     <identifier>id4</identifier> 
     <impact> 
      <product>BB</produit> 
     </impact> 
    </objet> 
    <object> 
     <identifier>id5</identifier> 
     <impact> 
      <product>AA</produit> 
     </impact> 
    </objet> 
    <object> 
     <identifier>id2</identifier> 
     <impact> 
      <product>XX</produit> 
     </impact> 
    </objet> 
    <object> 
     <identifier>id3</identifier> 
     <impact> 
      <product>XX</produit> 
     </impact> 
    </objet> 
</date> 
</evolutionlist> 

我的XSLT代码(不工作,虽然)是

<xsl:for-each select="//date"> 
    <tr> 
    <td> 
    <xsl:value-of select="./@id"/> 
    </td> 
    </tr> 
    <xsl:for-each select="./object"> 
    <xsl:choose> 
    <xsl:when test="impact/produit = 'XX'"> 
      <xsl:sort select="impact/produit" order="descending"/> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:sort select="identifiant"/> 
    </xsl:otherwise> 
    </xsl:choose> 

     ... 
</xsl:for-each> 

回答

1

你可以把一个<xsl:sort><xsl:for-each><xsl:apply-templates/>的开头,而不是在<choose>块。

您正在使用排序订购XX,所以我会假设这是在您的情况确定(例如:你没有一个名为ZZ产品,这将被放置在XX后)。如果不是这种情况,则不应使用sort作为该规则,而应使用与XX内容匹配的模板,并将它们放在最后。

此样式表使用原始样式表中的sort规则(按ID和产品字符串排序)生成您期望的结果。我将选择规则移到XPath谓词中,并使用模板而不是嵌套的for-each节点。

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 

    <xsl:template match="date"> 
      <xsl:apply-templates select="object"> 
       <xsl:sort select="impact/product[. = 'XX']" order="ascending"/> 
       <xsl:sort select="identifier"/> 
      </xsl:apply-templates> 
    </xsl:template> 

    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

你可以尝试一下在这个XSLT Fiddle

UPDATE在你实际上并不想为了XX产品的情况,但把它们放在最后,总是,您可以在处理其他元素后过滤这些元素并应用其模板。这其他样式表确实是:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 

    <xsl:template match="date"> 
     <xsl:apply-templates select="object[not(impact[product = 'XX'])]"> 
      <xsl:sort select="identifier"/> 
     </xsl:apply-templates> 
     <xsl:apply-templates select="object[impact[product = 'XX']]"/> 
    </xsl:template> 

    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

这里的另一个XSLT Fiddle这个例子。

+0

感谢您的帮助,更加清楚,不幸的是,我可以有ZZ产品,它根据自己的ID排序,只有XX产品必须出现在最后,对不起,我没有足够精确 – stackSaru

+0

这就是为什么我使用“when”条件 – stackSaru

+1

你不需要'when'。您可以选择模板和谓词,这也更有效。我添加了一个将'XX'元素放在最后的解决方案。 – helderdarocha

相关问题