2014-06-26 30 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

相關問題