0

I would need to sort an XML document that looks like follows:

<root xmlns="http://my.name.space.com">
    <product id="id001">
        <datafield name="Name" value="value 1"/>
        <datafield name="Description" value="descriptive text"/>
        <dataAttribute id="id002">
            <datafield name="Name" value="ZZZZZ"/>
            <datafield name="Start Date" value="16/01/2010 00:00:00"/>
            <datafield name="End Date" value=""/>
            <datafield name="Status" value="Active"/>
        </dataAttribute>
        <dataAttribute id="id003">
            <datafield name="Name" value="XXXXX"/>
            <datafield name="Start Date" value="16/01/2010 00:00:00"/>
            <datafield name="End Date" value=""/>
            <datafield name="Status" value="Active"/>
        </dataAttribute>
        <dataAttribute id="id004">
            <datafield name="Name" value="YYYYY"/>
            <datafield name="Start Date" value="16/01/2010 00:00:00"/>
            <datafield name="End Date" value=""/>
            <datafield name="Status" value="Active"/>
        </dataAttribute>
    </product>
</root>

The dataAttribute elements should be sorted, by the one which @name Attribute = "Name" but the sorting should occure by this element's @value attribute.

Do you have any hints on this?

Thank you very much!

Fritz

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
fritz
  • 13
  • 1
  • 2

1 Answers1

0

Well use xsl:sort with the proper select attribute:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0"
  xmlns:df="http://my.name.space.com"
  exclude-result-prefixes="df">

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

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

<xsl:template match="df:product">
  <xsl:copy>
    <xsl:apply-templates select="@* | *[not(self::df:dataAttribute)]"/>
    <xsl:apply-templates select="df:dataAttribute">
      <xsl:sort select="df:dataField[@name = 'Name']/@value"/>
    </xsl:apply-templates>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>
Martin Honnen
  • 160,499
  • 6
  • 90
  • 110
  • Hi, thanks for your fast answer! It works 99% perfect. There's just 2 minor problems: 1) I'm loosing my elements, directly below the element. and 2) I'm loosing the attributes from the element. Can you give me a hint, what's the problem? Thanks! – fritz Apr 03 '13 at 15:08
  • Ok, just found out how to copy the datafield elements below the product, by adding . Still open: how to copy the attributes from the element? Thanks! – fritz Apr 03 '13 at 15:19
  • I have edited the code to make sure the attributes of `product` are processed as well and the other child elements like `datafield` are also processed. There still could be a problem however if the input contains further elements after or in between of the `dataAttribute` elements. Let us know whether the input be be more complex than posted. – Martin Honnen Apr 03 '13 at 15:21
  • Instead of `xsl:apply-templates select="df:datafield` simply add `xsl:apply-templates select="@* | df:datafield"`. – Martin Honnen Apr 03 '13 at 15:35
  • Thank you very much! Works perfect now (no, there are no more elements / complexity) – fritz Apr 03 '13 at 20:02