2011-06-28 189 views
4

我需要一個小例子的幫助,這樣我才能更好地理解xsl:sortXSLT:屬性排序

我的XML數據的模樣:

<NewTerms> 
    <newTerm ID="3">Zebra</newTerm> 
    <newTerm ID="11">Horse</newTerm> 
    <newTerm ID="1">Cat</newTerm> 
    <newTerm ID="90">Lion</newTerm> 
    <newTerm ID="62">Jaguar</newTerm> 
    <newTerm ID="30">Cheetah</newTerm> 
    <newTerm ID="55">Deer</newTerm> 
    <newTerm ID="45">Buffalo</newTerm> 
    <newTerm ID="15">Dog</newTerm> 
</NewTerms ID="10"> 

,我想根據ID屬性對它們進行排序。我有XSL不工作:

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

    <xsl:output method="xml" indent="yes" omit-xml-declaration="no"/> 

    <xsl:template match="@*|node()[not(preceding::node()=.)]"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()[not(preceding::node()=.)]"> 
       <xsl:sort select="./@ID"/> 
      </xsl:apply-templates> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

我不知道xsl:sort功能是如何工作的。通過這個例子來幫助我更好地理解它。

+0

很高興看到[End-Tag]中的屬性(http://www.w3.org/TR/1998/REC-xml-19980210#NT-ETag):D –

+0

+1 basic但使用有問題。 –

回答

1

NewTerms的標籤標籤中的ID屬性似乎不合適。

以下XSL腳本排序數據上ID屬性:

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

    <xsl:output method="xml"/> 

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

    <xsl:template match="/NewTerms"> 
    <xsl:copy> 
     <xsl:apply-templates select="newTerm"> 
     <xsl:sort select="@ID" data-type="number" /> 
     </xsl:apply-templates> 
    </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 
+3

這些ID屬性值看起來像數字,因此按照請求進行排序可能需要''。默認的數據類型是「文本」,例如「110」的方式會在「12」之前結束。 –

+0

@馬丁,好點。更新了答案,以數字排序。 – rsp

+0

@馬丁:這是主要觀點。 –

0

正如在評論@ RSP的回答中指出,該default sort data-type是「文本」,但希望「號」。實際上,你可以用你自己的第一次嘗試做僅僅是一個變化後:

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

    <xsl:output method="xml" indent="yes" omit-xml-declaration="no"/> 

    <xsl:template match="@*|node()[not(preceding::node()=.)]"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()[not(preceding::node()=.)]"> 
     <xsl:sort select="./@ID" data-type="number" /> 
     </xsl:apply-templates> 
    </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

這可以讓你保持你的(低效率)重複檢查:

node()[not(preceding::node()=.)] 
4

你的變換是正確。您只錯過了指定默認爲「text」的data-type屬性,因此不適用於數字。

有關使用xsl:sort的更多信息,您可以看到specs和最近類似的question

以下幾點注意事項:

  • 可以省略./@ID因爲.選擇是在模板
  • 你並不需要檢查以這種方式在先節點的默認上下文節點,它沒有任何意義。

注意你只需要Identity Transformation懷着一種指令。

您的最終變換看起來像:

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

    <xsl:output method="xml" indent="yes" omit-xml-declaration="no"/> 
    <xsl:strip-space elements="*"/> 

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

</xsl:stylesheet> 

當應用到輸入(這裏有點修改,以解決您的結束標記錯字):

<NewTerms> 
    <newTerm ID="3">Zebra</newTerm> 
    <newTerm ID="11">Horse</newTerm> 
    <newTerm ID="1">Cat</newTerm> 
    <newTerm ID="90">Lion</newTerm> 
    <newTerm ID="62">Jaguar</newTerm> 
    <newTerm ID="30">Cheetah</newTerm> 
    <newTerm ID="55">Deer</newTerm> 
    <newTerm ID="45">Buffalo</newTerm> 
    <newTerm ID="15">Dog</newTerm> 
</NewTerms> 

生產:

<NewTerms> 
    <newTerm ID="1">Cat</newTerm> 
    <newTerm ID="3">Zebra</newTerm> 
    <newTerm ID="11">Horse</newTerm> 
    <newTerm ID="15">Dog</newTerm> 
    <newTerm ID="30">Cheetah</newTerm> 
    <newTerm ID="45">Buffalo</newTerm> 
    <newTerm ID="55">Deer</newTerm> 
    <newTerm ID="62">Jaguar</newTerm> 
    <newTerm ID="90">Lion</newTerm> 
</NewTerms> 
+0

+1有很好的解釋和簡單的解決方案 – cordsen

+0

@cordsen,謝謝感謝您的反饋。 –