title: XSLT 1.0: Transforming flat structure to nested with Muenschian grouping: avoid creation of spurious copies
body: <p>I am XSLT beginner, learning by example and by working on projects. Currently, I am working on creating grouped, nested structure from flat.</p>
  <p>Consider this sample xml input:</p>
  <pre><code>&lt;root&gt;
      &lt;a&gt;First text&lt;/a&gt;
      &lt;b&gt;Text&lt;/b&gt;
      &lt;c&gt;More text in c tag&lt;/c&gt;
      &lt;d&gt;There is even d tag&lt;/d&gt;
      &lt;a&gt;Another &quot;a&quot; test.&lt;/a&gt;
      &lt;b&gt;ěščřžýáíéúů&lt;/b&gt;
      &lt;b&gt;More b tags&lt;/b&gt;
      &lt;c&gt;One followed by c tag&lt;/c&gt;
      &lt;a&gt;Last a tag&lt;/a&gt;
      &lt;b&gt;This time only with b tag, but this goes on and on&lt;/b&gt;
  &lt;/root&gt;
  </code></pre>
  <p>And this XSLT:</p>
  <pre><code>&lt;xsl:stylesheet version=&quot;1.0&quot;
    xmlns:xsl=&quot;http://www.w3.org/1999/XSL/Transform&quot;&gt;
    &lt;xsl:output omit-xml-declaration=&quot;yes&quot; indent=&quot;yes&quot; method=&quot;xml&quot; encoding=&quot;utf-8&quot;/&gt;
    &lt;xsl:strip-space elements=&quot;*&quot;/&gt;
  
    &lt;xsl:output method=&quot;xml&quot; encoding=&quot;utf-8&quot;/&gt;
  
    &lt;xsl:key name=&quot;groupA&quot; match=&quot;b|c|d&quot; use=&quot;generate-id(preceding-sibling::a[1])&quot; /&gt;
    &lt;xsl:key name=&quot;groupB&quot; match=&quot;c|d&quot; use=&quot;generate-id(preceding-sibling::b[1])&quot;/&gt;
  
    &lt;xsl:template match=&quot;node() | @*&quot;&gt;
      &lt;xsl:copy&gt;
        &lt;xsl:apply-templates select=&quot;node() | @*&quot;/&gt;
      &lt;/xsl:copy&gt;
    &lt;/xsl:template&gt;
  
    &lt;xsl:template match=&quot;root&quot;&gt;
      &lt;wrapperTest&gt;
        &lt;xsl:apply-templates/&gt;
      &lt;/wrapperTest&gt;
    &lt;/xsl:template&gt;
  
    &lt;xsl:template match=&quot;root&quot;&gt;
      &lt;xsl:apply-templates select=&quot;@*|a&quot;/&gt;
      &lt;xsl:apply-templates select=&quot;@*|b&quot;/&gt;
    &lt;/xsl:template&gt;
  
    &lt;xsl:template match=&quot;a&quot;&gt;
      &lt;xsl:copy&gt;
        &lt;xsl:apply-templates select=&quot;key('groupA', generate-id())&quot; /&gt;
      &lt;/xsl:copy&gt;
    &lt;/xsl:template&gt;
    
    &lt;xsl:template match=&quot;b&quot;&gt;
      &lt;xsl:copy&gt;
        &lt;xsl:apply-templates select=&quot;key('groupB', generate-id())&quot; /&gt;
      &lt;/xsl:copy&gt;
    &lt;/xsl:template&gt;
  
  &lt;/xsl:stylesheet&gt;
  </code></pre>
  <p>The expected output is:</p>
  <pre><code>&lt;wrapperTest&gt;
      &lt;a&gt;First text
        &lt;b&gt;Text
          &lt;c&gt;More text in c tag&lt;/c&gt;
          &lt;d&gt;There is even d tag&lt;/d&gt;
        &lt;/b&gt;
      &lt;/a&gt;
      &lt;a&gt;Another &quot;a&quot; test.
        &lt;b&gt;ěščřžýáíéúů&lt;/b&gt;
        &lt;b&gt;More b tags
          &lt;c&gt;One followed by c tag&lt;/c&gt;
        &lt;/b&gt;
      &lt;/a&gt;
      &lt;a&gt;Last a tag
        &lt;b&gt;This time only with b tag, but this goes on and on&lt;/b&gt;
      &lt;/a&gt;
  &lt;/wrapperTest&gt;
  </code></pre>
  <p>In the transformation I created are excessive copies created and I have no idea why. I guess that the isuue I am hiting upon is basic in its nature, but I cant figure it out.</p>
  <p>The only limit for solution is, that preferably it should be in XSLT 1.0 (since the project is incorporated in <code>python</code> script with <code>lxml</code>). In the edge case, when this couldnt be achived with XSLT 1.0, I can accomodate for recent <code>saxon</code> version which removes any limitations ...</p>
  <p>I have already looked at answers <a href="https://stackoverflow.com/questions/872067/creating-a-nested-tree-structure-from-a-path-in-xslt">here</a>, <a href="https://stackoverflow.com/questions/4651257/xsl-to-create-nested-list-from-flat-tree-problem">here</a> and others, but most of them use either XSLT 2.0 or are very complicated for a beginner to knive through.</p>
  <p><strong>Final note:</strong> Ideally, proposed solution should be extensible in it nature, because the final form of my project should be also grouped by tag <code>&lt;c&gt;</code>, like so:</p>
  <pre><code>&lt;wrapperTest&gt;
      &lt;a&gt;First text
        &lt;b&gt;Text
          &lt;c&gt;More text in c tag
            &lt;d&gt;There is even d tag&lt;/d&gt;
          &lt;/c&gt;
        &lt;/b&gt;
      &lt;/a&gt;
      &lt;a&gt;Another &quot;a&quot; test.
        &lt;b&gt;ěščřžýáíéúů&lt;/b&gt;
        &lt;b&gt;More b tags
          &lt;c&gt;One followed by c tag&lt;/c&gt;
        &lt;/b&gt;
      &lt;/a&gt;
      &lt;a&gt;Last a tag
        &lt;b&gt;This time only with b tag, but this goes on and on&lt;/b&gt;
      &lt;/a&gt;
  &lt;/wrapperTest&gt;
  </code></pre>
  <p>Which I will happily do as learning excersize.</p>