按属性对节点内的多个XML元素进行排序

时间:2010-03-10 00:59:04

标签: xml sorting xslt

我已经尝试了几种我在这里找到的解决方案,但似乎没有一种解决方案适用于我正在使用的模型。在我的示例XML中,我试图将混合的章节按其正确的顺序排序。

源XML:

<?xml version="1.0" encoding="utf-8"?>  
<library>  
    <book>  
        <title>A Fascinating Tale</title>  
        <chapter num="4">
            <text>...and rambles to the end.</text>  
        </chapter>  
        <chapter num="2">  
            <text>The hero would...</text>  
        </chapter>  
        <chapter num="3">  
            <text>This went rambling on...</text>  
        </chapter>  
        <chapter num="1">  
            <text>Once upon a time...</text>  
        </chapter>  
    </book>  
</library>  

应该导致:

<?xml version="1.0" encoding="utf-8"?>  
<library>  
    <book>  
        <title>A Fascinating Tale</title>  
        <chapter num="1">  
            <text>Once upon a time...</text>  
        </chapter>  
        <chapter num="2">  
            <text>The hero would...</text>  
        </chapter>  
        <chapter num="3">  
            <text>This went rambling on...</text>  
        </chapter>  
        <chapter num="4">  
            <text>...and rambles to the end.</text>  
        </chapter>  
    </book>  
</library>  

所以从我在这里找到的样式表解决方案来看,我无法工作。我这太难了吗?看起来应该相当简单。

1 个答案:

答案 0 :(得分:1)

Altova XMLSpy拯救:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml"/>
    <!-- Identity transform - copies everything that doesn't have an explicit match below -->
    <xsl:template match="node() | @*">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
    <!-- Special handling for book element. Copy it, then any title and any chapter-->
    <!-- But sort any chapter elements by num attribute -->
    <xsl:template match="book">
        <xsl:copy>
            <xsl:apply-templates select="title"/>
            <xsl:apply-templates select="chapter">
                <xsl:sort select="@num"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>