[xsl] From flat to hierarchical structure

Subject: [xsl] From flat to hierarchical structure
From: "nick public nickpubl@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Wed, 22 Oct 2014 11:22:48 -0000
Hi people
I need to convert a flat structure like this

<root>
   <H>1</H>
   <I>1-1</I>
   <I>1-2</I>
   <I>1-3</I>
   <H>2</H>
   <I>2-1</I>
   <I>2-2</I>
 </root>

in one like this

<root>
   <H>
      1
      <I>1-1</I>
      <I>1-2</I>
      <I>1-3</I>
   </H>
   <H>
      2
      <I>2-1</I>
      <I>2-2</I>
   </H>
</root>

I'm tring the approch for-each on the source structure in this way

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
   <xsl:output method="xml" indent="yes"/>

   <xsl:template match="root">
      <root>
         <xsl:for-each select="child::node()">
            <xsl:if test="self::H">
               <H>
                  <xsl:copy-of select="@* | node()"/>
                  <xsl:call-template name="copyI"/>
               </H>
            </xsl:if>
         </xsl:for-each>
      </root>
   </xsl:template>

   <xsl:template name="copyI">
      <xsl:for-each select="following-sibling::node()">
         <xsl:choose>

            <xsl:when test="self::H">
               <!-- Should be fantastic to exit from the loop! -->
            </xsl:when>

            <xsl:when test="self:(idea)">
               <I>
                  <xsl:copy-of select="@* | node()"/>
               </I>
               <xsl:text>&#13;</xsl:text>
            </xsl:when>

         </xsl:choose>
      </xsl:for-each>
   </xsl:template>

</xsl:stylesheet>

Unfortunately, the best result that I can reach is this

<root>
   <H>
      1
      <I>1-1</I>
      <I>1-2</I>
      <I>1-3</I>
      <I>2-1</I>     wrong!
      <I>2-2</I>     wrong!
   </H>
   <H>
      2
      <I>2-1</I>
      <I>2-2</I>
   </H>
</root>

where       <I>2-1</I> and <I>2-2</I> under H1 are wrong.

The problem is that I cannot escape from the template copyI when it finds and H.
Since the source structure is flat (all siblings), I'm afraid that a
recursive copyI doesn't help.

Any suggestion?

Thanks a lot.
Nicola

Current Thread