title: Putting a wrapper around a group of elements in XSLT
body: <p>I'm using XSLT to transform an XML document from one doctype to another.  In simplified form, I have something that looks like this:</p>
  
  <pre><code>&lt;section&gt;
      &lt;title&gt;Title&lt;/title&gt;
      &lt;a&gt;content1&lt;/a&gt;
      &lt;a&gt;content2&lt;/a&gt;
      &lt;a&gt;content3&lt;/a&gt;
      &lt;a&gt;content4&lt;/a&gt;
      &lt;b&gt;other content&lt;/b&gt;
      &lt;a&gt;content5&lt;/a&gt;
      &lt;a&gt;content6&lt;/a&gt;
      &lt;a&gt;content7&lt;/a&gt;
      &lt;c&gt;other content&lt;/c&gt;
      &lt;a&gt;content8&lt;/a&gt;
      &lt;a&gt;content9&lt;/a&gt;
      &lt;a&gt;content10&lt;/a&gt;
  &lt;/section&gt;
  </code></pre>
  
  <p>What I want is to place a wrapper around the groups of <code>&lt;a&gt;</code> elements, so the translated result looks like this:</p>
  
  <pre><code>&lt;section&gt;
      &lt;title&gt;Title&lt;/title&gt;
      &lt;a-wrapper&gt;
          &lt;a&gt;content1&lt;/a&gt;
          &lt;a&gt;content2&lt;/a&gt;
          &lt;a&gt;content3&lt;/a&gt;
          &lt;a&gt;content4&lt;/a&gt;
      &lt;/a-wrapper&gt;
      &lt;b&gt;other content&lt;/b&gt;
      &lt;a-wrapper&gt;
          &lt;a&gt;content5&lt;/a&gt;
          &lt;a&gt;content6&lt;/a&gt;
          &lt;a&gt;content7&lt;/a&gt;
      &lt;/a-wrapper&gt;
      &lt;c&gt;other content&lt;/c&gt;
      &lt;a-wrapper&gt;
          &lt;a&gt;content8&lt;/a&gt;
          &lt;a&gt;content9&lt;/a&gt;
          &lt;a&gt;content10&lt;/a&gt;
      &lt;/a-wrapper&gt;
  &lt;/section&gt;
  </code></pre>
  
  <p>My current template looks like this:</p>
  
  <pre><code>&lt;xsl:template match="a"&gt;
      &lt;xsl:choose&gt;
          &lt;xsl:when test="not(preceding-sibling::a)"&gt;
              &lt;xsl:element name="a-wrapper"&gt;
                  &lt;xsl:element name="a"&gt;
                      &lt;xsl:apply-templates/&gt;
                  &lt;/xsl:element&gt;
                  &lt;xsl:apply-templates select="following-sibling::a[generate-id(preceding-sibling::a[last()]) = generate-id(current())]"/&gt;
              &lt;/xsl:element&gt;
          &lt;/xsl:when&gt;
          &lt;xsl:otherwise&gt;
              &lt;xsl:element name="a"&gt;
                  &lt;xsl:apply-templates/&gt;
              &lt;/xsl:element&gt;
          &lt;/xsl:otherwise&gt;
      &lt;/xsl:choose&gt;
  &lt;/xsl:template&gt;
  </code></pre>
  
  <p>This gets me partway there.  The problem is that the select clause in the apply-templates tag is getting all of the <code>&lt;a&gt;</code> tags, when I want it to stop at the first non-<code>&lt;a&gt;</code> tag, i.e., the processing of the first <code>&lt;a&gt;</code> tag is placing all 10 <code>&lt;a&gt;</code> tags within the first <code>&lt;a-wrapper&gt;</code>, when I only want the first four.  This also has the effect of inserting nested <code>&lt;a-wrapper&gt;</code> tags, like the one generated by the fifth <code>&lt;a&gt;</code> tag, and that's not allowed by the DTD.</p>
  
  <p>So the question is, how do I select a subset of following-siblings that ends with the first non-<code>&lt;a&gt;</code> tag?</p>