tags:

views:

55

answers:

3

I have an XML file whose contents I want to sort by document order (basically in the order that the items were written out).

I currently use the following code:

<xsl:template match="/Error">
        <xsl:apply-templates>
            <xsl:sort select="position()" order="descending" />
        </xsl:apply-templates>
</xsl:template>

<xsl:template match="/Error/Warning">
<!-- etc -->
</xsl:template>

Example XML (data replaced for ease of reading):

<Error>
<Warning data="stuff" timestamp="08:26:17 2010/08/01">CODE.1</Warning>
<Clear data="stuff" timestamp="08:26:36 2010/08/01">CODE.2</Clear>
<Warning data="stuff" timestamp="08:36:00 2010/08/01">CODE.3</Warning>
<Clear data="stuff" timestamp="08:36:56 2010/08/01">CODE.4</Clear>
<Warning data="stuff" timestamp="08:40:31 2010/08/01">CODE.5</Warning>
</Error>

This, however, seems to give odd results as it seems to be in no particular order! Any ideas?

Removing the sort seems to make it work properly - will this reliably order it in write-order or is that not guaranteed?

+1  A: 

arent you missing what nodes you want to apply an template to?

for instance:

<xsl:apply-templates select="/Error/messages" />

would be nice to have the xml you are working with when dealing with a xslt issue.

Updated with a bit more info...
Chris
+1  A: 

<xsl:apply-templates /> operates over the selected nodeset in document order, remove the sort element, and this will work as desired. See: Applying Template Rules

Paul Butcher
+1  A: 

Shouldn't it be like this? using the select attribute on apply-templates?

<xsl:template match="/Error">
  <xsl:apply-templates select="./Warning" />
</xsl:template>

<xsl:template match="/Error/Warning">
  <!-- etc -->
</xsl:template>

You should get the output in the order it is in the XML source.

@Chris If you want to filter the children of Error, and only have Warning elements, it is better to use `xsl:apply-templates/@select`, as defined in this answer, than to just use `xsl:template/@match`
Paul Butcher