2010-11-03 166 views
14

我不確定xsl:sort指令是如何工作的。我需要通過他們的標籤名稱來排序元素(用於區分),而我似乎無法想出如何完成這項工作。我的第一個雖然是修改身份轉換,只是修改它包括一個排序聲明,但我不確定如何做到這一點。XSLT按名稱排序節點?

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

+0

請提供一個小的源XML文檔以及轉換的預期結果。 – 2010-11-03 20:04:13

+0

好問題,+1。查看我的答案,獲得一個完整的解決方案,它還可以對屬性進行排序併發出警告 – 2010-11-03 20:14:36

回答

23

這種轉變

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

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

    <xsl:apply-templates select="node()"> 
    <xsl:sort select="name()"/> 
    </xsl:apply-templates> 
    </xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 

當這個XML文檔施加:

<t b="x" c="y" a="t"> 
    <c/> 
    <b/> 
    <a/> 
</t> 

產生想排序輸出

<t a="t" b="x" c="y"> 
    <a></a> 
    <b></b> 
    <c></c> 
</t> 

請注意

  1. 不僅元素,還屬性進行排序(後者是依賴於實現,但適用於MSXML)。

  2. 使用排序XML爲diff文件是不可靠的,因爲XML文檔轉換成排序的表示是不是1:1的映射。

+0

如果通過DOM純粹訪問XML結構,爲什麼排序後的文檔不能被區分? – 2010-11-03 20:20:56

+0

@ Stefan-Kendall:因爲一個元素可能具有相同數量的相同名稱的子元素(在這兩個文檔中),但在每個文檔中的順序完全不同。這兩個文件將被轉換爲產生相同的子元素列表,差異操作(或只是個人觀察)不會發現任何差異。 – 2010-11-03 21:47:50

+0

無論如何,在我解析的文檔中不保證順序,同一級別的任何東西都是等價的,所以我猜這應該起作用。 – 2010-11-03 22:06:20