title: XSLT every nth node with a filter
body: <p>I'm using XSLT for some output formatting, and I want a wrapper element around every N nodes of the output. I've read <a href="https://stackoverflow.com/questions/4010277/xslt-adding-trtr-every-n-node">xslt - adding &lt;/tr&gt;&lt;tr&gt; every n node?</a>, but my problem is that the source nodes have to come from a lookup:</p>
  
  <pre><code>&lt;xsl:for-each select="key('items-by-product', $productid)"&gt;
  </code></pre>
  
  <p>rather than just a template match. All the examples I've found assume that the nodes you want are all next to each other, and they're just counting siblings. </p>
  
  <p>I have a solution that works for me: </p>
  
  <pre><code>&lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" &gt;
    &lt;xsl:variable name='num_per_div' select='2' /&gt;
    &lt;xsl:variable name='productid' select='1' /&gt;
    &lt;xsl:output method="xml" indent="yes"/&gt;
    &lt;xsl:key name="items-by-product" match="item" use="productid"/&gt;
    &lt;xsl:template match="data"&gt;
      &lt;output&gt;
        &lt;xsl:for-each select="key('items-by-product', $productid)"&gt;
          &lt;xsl:variable name='pos' select='position()' /&gt;
          &lt;xsl:if test="position() = 1 or not((position()-1) mod $num_per_div)"&gt;
            &lt;outer pos="{$pos}"&gt;
              &lt;xsl:for-each select="key('items-by-product', $productid)"&gt;
                &lt;xsl:variable name='ipos' select='position()' /&gt;
                &lt;xsl:if test="$ipos &gt;= $pos and $ipos &amp;lt; $pos + $num_per_div"&gt;
                  &lt;inner&gt;
                    &lt;xsl:value-of select="itemid"/&gt;
                  &lt;/inner&gt;
                &lt;/xsl:if&gt;
              &lt;/xsl:for-each&gt;
            &lt;/outer&gt;
          &lt;/xsl:if&gt;
        &lt;/xsl:for-each&gt;      
      &lt;/output&gt;
    &lt;/xsl:template&gt;
  &lt;/xsl:stylesheet&gt;
  </code></pre>
  
  <p>with data </p>
  
  <pre><code>&lt;data&gt;
    &lt;item&gt;
      &lt;productid&gt;1&lt;/productid&gt;
      &lt;itemid&gt;1&lt;/itemid&gt;
    &lt;/item&gt;
    &lt;item&gt;
      &lt;productid&gt;1&lt;/productid&gt;
      &lt;itemid&gt;2&lt;/itemid&gt;
    &lt;/item&gt;
    &lt;item&gt;
      &lt;productid&gt;2&lt;/productid&gt;
      &lt;itemid&gt;A&lt;/itemid&gt;
    &lt;/item&gt;
    &lt;item&gt;
      &lt;productid&gt;1&lt;/productid&gt;
      &lt;itemid&gt;3&lt;/itemid&gt;
    &lt;/item&gt;
    &lt;item&gt;
      &lt;productid&gt;2&lt;/productid&gt;
      &lt;itemid&gt;B&lt;/itemid&gt;
    &lt;/item&gt;
    &lt;item&gt;
      &lt;productid&gt;1&lt;/productid&gt;
      &lt;itemid&gt;4&lt;/itemid&gt;
    &lt;/item&gt;
  &lt;/data&gt;
  </code></pre>
  
  <p>which produces</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;output&gt;
    &lt;outer pos="1"&gt;
      &lt;inner&gt;1&lt;/inner&gt;
      &lt;inner&gt;2&lt;/inner&gt;
    &lt;/outer&gt;
    &lt;outer pos="3"&gt;
      &lt;inner&gt;3&lt;/inner&gt;
      &lt;inner&gt;4&lt;/inner&gt;
    &lt;/outer&gt;
  &lt;/output&gt;
  </code></pre>
  
  <p>But this is looping through all the nodes for each node, which strikes me as inefficient. </p>
  
  <p>Is there a better approach that will produce the same output more efficiently? Can the following-sibling techniques work with a filter?</p>