2012-06-12 114 views
1

我是XSLT的新手。我只是想出一個問題,並希望有人能夠提供幫助。XSLT,如何按元素名稱排序

假設我有一個XML源,

<?xml version="1.0"?> 
<docroot> 
    <vc6>foo</vc6> 
    <vc7>bar7</vc7> 
    <vc8 arch="x64">amd64demo</vc8> 
    <vc7>foo7</vc7> 
    <vc6>bar</vc6> 
</docroot> 

我希望把它變成:應該由元素名稱進行排序

<?xml version="1.0"?> 
<docroot> 
    <vc6>bar</vc6> 
    <vc6>foo</vc6> 
    <vc7>bar7</vc7> 
    <vc7>foo7</vc7> 
    <vc8 arch="x64">amd64demo</vc8> 
</docroot> 

就是 1子元素,所以來之前。 2.如果兩個孩子有相同的元素名稱,他們應該按照他們的文本值排序,所以'bar'超過'foo'。

如何編寫xsl?謝謝。

回答

1

this answer中有一些如何使用xsl:sort的例子。像這樣的東西應該爲你工作:legoscia的回答

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

謝謝你,你得到正確的答案。但是,你能否更新答案,以便可以複製屬性?目前,在源xml中的屬性xsltproc 2.7.8中說:「必須在任何子節點之前添加屬性節點到元素」。 –

+0

已更新。它現在工作好嗎? – legoscia

+0

不,這仍然是錯誤的。如果有一個名爲AA的子元素和一個名爲ZZ的屬性,它將嘗試將該子元素放在該屬性之前。 –

3

修訂:

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

糟糕,您的兩個元素不成對。即使我並排複製結束標記,以使其格式良好。 xsltproc 2.7.8只輸出'''',而不是預期的結果。 –

+0

我糾正了這個錯誤。儘管如此,仍然未經測試。 –