views:

159

answers:

1

I've tried several of the solutions that I've found here, but none seem to work on the model that I'm using. In my example XML, I'm trying to sort the mixed up chapters, into their proper sequence.

Source 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>  

Should result in:

<?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>  

So from the stylesheet solutions I've found here, I can't get any to work. Am I making this too difficult? It seems like it should be fairly straightforward.

A: 

Altova XMLSpy to the rescue:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
    <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>
John Saunders
Not that I don't love me some XmlSpy, but what does the XML editor you're using have to do with your answer?
Robert Rossney
Brilliant! This works perfectly. Thanks so much for this. Now I need to toddle off, and compare this code to other samples that I tried, and try to comprehend what about this worked, and what about the others didn't. Again, thank you.
LOlliffe
@Robert: it's what got me an answer 17 minutes after I saw the question. Credit where due.
John Saunders
I'm probably just out of the loop. I haven't used XmlSpy in a few years; they must have added some transform-building tool to it. Your comment read to me like "Notepad to the rescue!"
Robert Rossney
@Robert: there's another tool (MapForce) which can generate transforms. I just used the editor and debugger, which are part of XMLSpy.
John Saunders