title: XSLT: From flat to hierarchic​al structure
body: <p>I need to convert a flat structure like this</p>
  
  <pre><code> &lt;root&gt;
      &lt;H&gt;1&lt;/H&gt;
      &lt;I&gt;1-1&lt;/I&gt;
      &lt;I&gt;1-2&lt;/I&gt;
      &lt;I&gt;1-3&lt;/I&gt;
      &lt;H&gt;2&lt;/H&gt;
      &lt;I&gt;2-1&lt;/I&gt;
      &lt;I&gt;2-2&lt;/I&gt;
    &lt;/root&gt;
  </code></pre>
  
  <p>in one like this</p>
  
  <pre><code>   &lt;root&gt;
          &lt;H&gt;
             1
             &lt;I&gt;1-1&lt;/I&gt;
             &lt;I&gt;1-2&lt;/I&gt;
             &lt;I&gt;1-3&lt;/I&gt;
          &lt;/H&gt;
          &lt;H&gt;
             2
             &lt;I&gt;2-1&lt;/I&gt;
             &lt;I&gt;2-2&lt;/I&gt;
          &lt;/H&gt;
       &lt;/root&gt;
  </code></pre>
  
  <p>I'm trying the approach for-each on the source structure in this way</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
   &lt;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"
   &gt;
      &lt;xsl:output method="xml" indent="yes"/&gt;
  
      &lt;xsl:template match="root"&gt;
         &lt;root&gt;
            &lt;xsl:for-each select="child::node()"&gt;
               &lt;xsl:if test="self::H"&gt;
                  &lt;H&gt;
                     &lt;xsl:copy-of select="@* | node()"/&gt;
                     &lt;xsl:call-template name="copyI"/&gt;
                  &lt;/H&gt;
               &lt;/xsl:if&gt;
            &lt;/xsl:for-each&gt;
         &lt;/root&gt;
      &lt;/xsl:template&gt;
  
      &lt;xsl:template name="copyI"&gt;
         &lt;xsl:for-each select="following-sibling::node()"&gt;
            &lt;xsl:choose&gt;
  
               &lt;xsl:when test="self::H"&gt;
                  &lt;!-- Should be fantastic to exit from the loop! --&gt;
               &lt;/xsl:when&gt;
  
               &lt;xsl:when test="self::I"
                  &lt;I&gt;
                     &lt;xsl:copy-of select="@* | node()"/&gt;
                  &lt;/I&gt;
                  &lt;xsl:text&gt;&amp;#13;&lt;/xsl:text&gt;
               &lt;/xsl:when&gt;
  
            &lt;/xsl:choose&gt;
         &lt;/xsl:for-each&gt;
      &lt;/xsl:template&gt;
  
   &lt;/xsl:stylesheet&gt;
  </code></pre>
  
  <p>Unfortunately, the best result that I can reach is this</p>
  
  <pre><code>&lt;root&gt;
      &lt;H&gt;
         1
         &lt;I&gt;1-1&lt;/I&gt;
         &lt;I&gt;1-2&lt;/I&gt;
         &lt;I&gt;1-3&lt;/I&gt;
         &lt;I&gt;2-1&lt;/I&gt;     wrong!
         &lt;I&gt;2-2&lt;/I&gt;     wrong!
      &lt;/H&gt;
      &lt;H&gt;
         2
         &lt;I&gt;2-1&lt;/I&gt;
         &lt;I&gt;2-2&lt;/I&gt;
      &lt;/H&gt;
   &lt;/root&gt;
  </code></pre>
  
  <p>where       <code>&lt;I&gt;2-1&lt;/I&gt;</code> and <code>&lt;I&gt;2-2&lt;/I&gt;</code> under H1 are wrong.</p>
  
  <p>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.</p>
  
  <p>Any suggestion?</p>
  
  <p>Thanks a lot.
   Nicola</p>
  
  <h1>How to extend your solution?</h1>
  
  <p>Tomalak, thank you very much for your help.
  Really, my needs is a bit more complicated and your solution is not scalable.
  In my source is optionally presents a <code>&lt;C&gt;</code> third level hierarchically dependent to <code>&lt;I&gt;</code></p>
  
  <pre><code>&lt;root&gt;
     &lt;H&gt;1&lt;/H&gt;
     &lt;I&gt;1-1&lt;/I&gt;
     &lt;C&gt;1-1-1&lt;/C&gt;
     &lt;I&gt;1-2&lt;/I&gt;
     &lt;C&gt;1-2-1&lt;/C&gt;
     &lt;I&gt;1-3&lt;/I&gt;
     &lt;H&gt;2&lt;/H&gt;
     &lt;I&gt;2-1&lt;/I&gt;
     &lt;I&gt;2-2&lt;/I&gt;
     &lt;C&gt;2-2-1&lt;/C&gt;
  &lt;/root&gt;
  </code></pre>
  
  <p>and the expected output is </p>
  
  <pre><code>&lt;root&gt;
     &lt;H&gt;1
      &lt;I&gt;1-1&lt;C&gt;1-1-1&lt;/C&gt;&lt;/I&gt;
      &lt;I&gt;1-2&lt;C&gt;1-2-1&lt;/C&gt;&lt;/I&gt;
      &lt;I&gt;1-3&lt;/I&gt;
     &lt;/H&gt;
     &lt;H&gt;2
      &lt;I&gt;2-1&lt;/I&gt;
      &lt;I&gt;2-2&lt;C&gt;2-2-1&lt;/C&gt;&lt;/I&gt;
     &lt;/H&gt;
  &lt;/root&gt;
  </code></pre>
  
  <p>Thanks a lot again
  Nicola</p>