tags:

views:

240

answers:

2

I'm trying to figure out how to preserve the whitespace nodes between the nodes I'm sorting. Here is an example.

Input:

<a>
    <b>
        <c>
            <d>world</d>
        </c>
        <c>
            <d>hello</d>
        </c>
    </b>
    <e>some other stuff</e>
</a>

Desired output:

<a>
    <b>
        <c>
            <d>hello</d>
        </c>
        <c>
            <d>world</d>
        </c>
    </b>
    <e>some other stuff</e>
</a>

Here is my xslt:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;

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

    <xsl:template match="a/b">
        <xsl:copy>
            <xsl:apply-templates select="c">
                <xsl:sort select="d"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

And when I run it through xsltproc, I get this:

<a>
    <b><c>
            <d>hello</d>
        </c><c>
            <d>world</d>
        </c></b>
    <e>some other stuff</e>
</a>

I'd rather not run it through tidy afterward. Ideas?

+2  A: 

You are going to want to add these two lines to the top of your stylesheet:

<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>

The first line strips all whitespace from the document and the second one indents the output.

Andrew Hare
+1  A: 

Your second template matches all b, but applies templates only on the c elements. The contained text-nodes are discarded. That's why you don't see whitespace between the b and c elements in the output.

You'll have to reformat the tree, as the text nodes will not look pretty after reordering (even if you manage to include them). Andrews solution will do that.

Teun D