[xsl] copying complete document, but sort specific childnodes

Subject: [xsl] copying complete document, but sort specific childnodes
From: "Marc Harding | marcharding.de" <info@xxxxxxxxxxxxxx>
Date: Fri, 4 Sep 2009 14:23:38 +0200
hello,

i try to copy an xml document and want to sort specific childnodes of
that document, the rest of the document structure should stay the
same. i nearly got it working, but nested group tags loose their
position after the transform process.

i attached my source document, xsl and the expected and real result. i
would be great it somebody knows how to do this. (i hope i didn't post
too much code, i just want to make my problem clear)

thanks,
marc

--

my source document:

<document>
	<group id="group_abc123">
		<item id="123456" sort-order="2">
			<childitem id="bar">foo</childitem>
			<childitem id="text">1</childitem>
		</item>
		<item id="123456" sort-order="1">
			<childitem id="bar">foo</childitem>
			<childitem id="text">1</childitem>
		</item>	
		<item id="123456" sort-order="3">
			<childitem id="bar">foo</childitem>
			<childitem id="text">1</childitem>
		</item>
		<group id="group_def123">
			<item id="123456" sort-order="2">
				<childitem id="bar">foo</childitem>
				<childitem id="text">1</childitem>
			</item>
			<item id="123456" sort-order="1">
				<childitem id="bar">foo</childitem>
				<childitem id="text">1</childitem>
			</item>	
			<item id="123456" sort-order="3">
				<childitem id="bar">foo</childitem>
				<childitem id="text">1</childitem>
			</item>
			<item id="123456" sort-order="4">
				<childitem id="bar">foo</childitem>
				<childitem id="text">1</childitem>
			</item>
		</group>	
		<item id="123456" sort-order="4">
			<childitem id="bar">foo</childitem>
			<childitem id="text">1</childitem>
		</item>
	</group>
	<group id="group_abc456">
		<item id="123456" sort-order="2">
			<childitem id="bar">foo</childitem>
			<childitem id="text">1</childitem>
		</item>
		<item id="123456" sort-order="1">
			<childitem id="bar">foo</childitem>
			<childitem id="text">1</childitem>
		</item>	
		<item id="123456" sort-order="3">
			<childitem id="bar">foo</childitem>
			<childitem id="text">1</childitem>
		</item>
		<item id="123456" sort-order="4">
			<childitem id="bar">foo</childitem>
			<childitem id="text">1</childitem>
		</item>
	</group>
</document>

--

my xsl:

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
xmlns:php="http://php.net/xsl"; exclude-result-prefixes="php">

<xsl:output method="xml" encoding="UTF-8" indent="yes"
omit-xml-declaration="yes" />

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

<xsl:template match="group">
	<xsl:element name="{name(.)}">
		<xsl:for-each select="@*">
			<xsl:attribute name="{name(.)}"><xsl:value-of select="." /></xsl:attribute>
		</xsl:for-each>
		<xsl:apply-templates>
			<xsl:sort select="@sort-order" data-type="number"/>
		</xsl:apply-templates>
	</xsl:element>
</xsl:template>

</xsl:stylesheet>

--

expected result:

<?xml version="1.0" encoding="UTF-8"?>
<document>
  <group id="group_abc123">
      <item id="123456" sort-order="1">
        <childitem id="bar">foo</childitem>
        <childitem id="text">1</childitem>
      </item>
      <item id="123456" sort-order="2">
        <childitem id="bar">foo</childitem>
        <childitem id="text">1</childitem>
      </item>
      <item id="123456" sort-order="3">
        <childitem id="bar">foo</childitem>
        <childitem id="text">1</childitem>
      </item>
      <group id="group_def123">
         <item id="123456" sort-order="1">
           <childitem id="bar">foo</childitem>
           <childitem id="text">1</childitem>
         </item>
         <item id="123456" sort-order="2">
           <childitem id="bar">foo</childitem>
           <childitem id="text">1</childitem>
         </item>
         <item id="123456" sort-order="3">
           <childitem id="bar">foo</childitem>
           <childitem id="text">1</childitem>
         </item>
         <item id="123456" sort-order="4">
           <childitem id="bar">foo</childitem>
           <childitem id="text">1</childitem>
         </item>
     </group>
      <item id="123456" sort-order="4">
        <childitem id="bar">foo</childitem>
        <childitem id="text">1</childitem>
      </item>
  </group>
  <group id="group_abc456">
    <item id="123456" sort-order="1">
      <childitem id="bar">foo</childitem>
      <childitem id="text">1</childitem>
    </item>
    <item id="123456" sort-order="2">
      <childitem id="bar">foo</childitem>
      <childitem id="text">1</childitem>
    </item>
    <item id="123456" sort-order="3">
      <childitem id="bar">foo</childitem>
      <childitem id="text">1</childitem>
    </item>
    <item id="123456" sort-order="4">
      <childitem id="bar">foo</childitem>
      <childitem id="text">1</childitem>
    </item>
  </group>
</document>

--

given result:

<?xml version="1.0" encoding="UTF-8"?>
<document>
  <group id="group_abc123">
    <group id="group_def123">
      <item id="123456" sort-order="1">
        <childitem id="bar">foo</childitem>
        <childitem id="text">1</childitem>
      </item>
      <item id="123456" sort-order="2">
        <childitem id="bar">foo</childitem>
        <childitem id="text">1</childitem>
      </item>
      <item id="123456" sort-order="3">
        <childitem id="bar">foo</childitem>
        <childitem id="text">1</childitem>
      </item>
      <item id="123456" sort-order="4">
        <childitem id="bar">foo</childitem>
        <childitem id="text">1</childitem>
      </item>
    </group>
    <item id="123456" sort-order="1">
      <childitem id="bar">foo</childitem>
      <childitem id="text">1</childitem>
    </item>
    <item id="123456" sort-order="2">
      <childitem id="bar">foo</childitem>
      <childitem id="text">1</childitem>
    </item>
    <item id="123456" sort-order="3">
      <childitem id="bar">foo</childitem>
      <childitem id="text">1</childitem>
    </item>
    <item id="123456" sort-order="4">
      <childitem id="bar">foo</childitem>
      <childitem id="text">1</childitem>
    </item>
  </group>
  <group id="group_abc456">
    <item id="123456" sort-order="1">
      <childitem id="bar">foo</childitem>
      <childitem id="text">1</childitem>
    </item>
    <item id="123456" sort-order="2">
      <childitem id="bar">foo</childitem>
      <childitem id="text">1</childitem>
    </item>
    <item id="123456" sort-order="3">
      <childitem id="bar">foo</childitem>
      <childitem id="text">1</childitem>
    </item>
    <item id="123456" sort-order="4">
      <childitem id="bar">foo</childitem>
      <childitem id="text">1</childitem>
    </item>
  </group>
</document>

Current Thread