使用Xsl 來替 Xml文件排序
參考文獻:Sorting an XML document in C# using XSL
Paul大師很棒的做出一個很簡單的sample code
讓我們只要用
<xsl:sort>
<xsl:copy-of>
可以馬上將Xml Document 排序.
以下為延伸的應用, 至於C#程式碼我就不PO文, 請參考Paul大師的samle
一、屬性篇
因為本人習慣用attribute, 所以改了一下
二、文字篇
當然也可以針對文字排序
三、正序篇
範例是用倒序, 我們可以改成正序
四、多層次篇
以上都只是xsl的基本功,
但如同往常, 只要碰到要跑loop或是要遞迴的, 一定會踢到鐵板
我的資料如下: 是多層的, 而且值是放在attribute
<Link ID="Q1" path="我的最愛">
<Link ID="Q11" path="建築">
<Link ID="Q111" path="設計師">
<Link ID="Q1111" path="隈研吾">
<Link ID="Q11111" path="三多利美術館" />
<Link ID="Q11112" path="森舞台" />
</Link>
<Link ID="Q1112" path="謝瑞夫" />
</Link>
<Link ID="Q112" path="營造商">
</Link>
</Link>
</Link>
<Link ID="Q2" path="公司系統" />
</Links>
而程式希望各項目能夠依 ID 在自己的層次中倒序.
首先 <xsl:copy-of> 會把所有的子項目都倒出來, 所以不適合
改用 <xsl:copy> 原本預期它將整個項目包含屬性一次複製, 結果它很懶, 所以只好加一句for-each讓它跑一次loop
<xsl:for-each select="./@*">
<xsl:copy />
</xsl:for-each>
另外要讓它向下探勘項目也花了一點功夫
<xsl:for-each select=".">
<xsl:apply-templates select="Link" >
<xsl:sort select="@ID" data-type="text" order="descending"/>
</xsl:apply-templates>
</xsl:for-each>
完整Xsl 如下:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="Links">
<xsl:copy>
<xsl:for-each select=".">
<xsl:apply-templates select="Link" >
<xsl:sort select="@ID" data-type="text" order="descending"/>
</xsl:apply-templates>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:template match="Link" >
<xsl:copy>
<!-- 複製屬性 -->
<xsl:for-each select="./@*">
<xsl:copy />
</xsl:for-each>
<!-- 向下探勘 -->
<xsl:for-each select=".">
<xsl:apply-templates select="Link" >
<xsl:sort select="@ID" data-type="text" order="descending"/>
</xsl:apply-templates>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
輸出結果如下:
<Links>
<Link ID="Q2" path="公司系統"/>
<Link ID="Q1" path="我的最愛">
<Link ID="Q11" path="建築">
<Link ID="Q112" path="營造商"/>
<Link ID="Q111" path="設計師">
<Link ID="Q1112" path="謝瑞夫"/>
<Link ID="Q1111" path="隈研吾">
<Link ID="Q11112" path="森舞台"/>
<Link ID="Q11111" path="三多利美術館"/>
</Link>
</Link>
</Link>
</Link>
</Links>
本來是想用LINQ2XML 做的, 但剛好那個Site只支援 .NET 2.0 (有機會再分享囉)