RE: [xsl] Dirty Input

Subject: RE: [xsl] Dirty Input
From: "Khorasani, Houman" <Houman.Khorasani@xxxxxxxxxxxx>
Date: Thu, 20 Jul 2006 15:37:21 +0100
Hi David,

Wow XSLT 2.0 is really much more efficient. So much less code!! That's
great!

You had forgotten to put the <Devices> element around the <device>
elements. ;o)  I just have re-added that and it works perfect!!! Many
Thanks!!!

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
	<xsl:strip-space elements="*"/>
	<xsl:output indent="yes"/>

	<xsl:template match="*">
		<xsl:copy>
			<xsl:copy-of select="@*"/>
			<xsl:apply-templates/>
		</xsl:copy>
	</xsl:template>

	<xsl:template match="Devices">
		<xsl:element name="Devices">
			<xsl:for-each-group select="*"
group-starting-with="DeviceKey">
				<device>
					<xsl:apply-templates
select="current-group()"/>
				</device>
			</xsl:for-each-group>
		</xsl:element>
	</xsl:template>
</xsl:stylesheet>

May you please send me Jenni's site?

The solution is fantastic!! Didn't expect it would be so little code. :)

Thanks
Houman



-----Original Message-----
From: David Carlisle [mailto:davidc@xxxxxxxxx]
Sent: 20 July 2006 12:12
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: Re: [xsl] Dirty Input



> The tag <Devices> contains elements <a>, <b> and <c> in that order
It's good not to confuse "tag" with "element", the tag <Devices> just
contains the element name "Devices", being a start tag it may also have
contained some attributes, but start tags never contain elements.

> Input file:
It's helpful if you make the example input well formed (I added a top
level element <x>...</x> around it all so that it could be passed as
input to xsl)



This sounds like a standard grouping problem, see Jeni's site for xslt1
solutions or in xslt2 your description is exactly the description of
group-starting-with, so you just need something like:



<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

  <xsl:strip-space elements="*"/>
  <xsl:output indent="yes"/>
  <xsl:template match="*">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="Devices">
    <xsl:for-each-group select="*" group-starting-with="a">
      <device>
	<xsl:apply-templates select="current-group()"/>
      </device>
    </xsl:for-each-group>
  </xsl:template>

</xsl:stylesheet>


which produces


$ saxon8 grp.xml grp.xsl
<?xml version="1.0" encoding="UTF-8"?>
<x>
   <bla>x</bla>
   <bla>x</bla>
    <device>
      <a>
         <a2>1</a2>
      </a>
      <b>
         <b2>
            <b3>1</b3>
            <b4>1</b4>
         </b2>
         <b2i>
            <b3i>1</b3i>
            <b4i>1</b4i>
         </b2i>
                ...
        </b>
      <c>1</c>
   </device>
   <device>
      <a>
         <a2>1</a2>
      </a>
      <b>
         <b2>
            <b3>1</b3>
            <b4>1</b4>
         </b2>
         <b2i>
            <b3i>1</b3i>
            <b4i>1</b4i>
         </b2i>
                ...
        </b>
      <c>1</c>
   </device>
</x>

Current Thread