title: XSLT, sorting, and position()
body: <p>Starting to work with XSLT, that's fun, I like the principal although it will take a little time to get used to. Now... I already ran in a problem which I'm wondering about and maybe someone could enlighten me about it.</p>
  
  <p>I have a set of boxes with a priority. The box with the smaller priority appears first. This works great. However, I'd like to place my boxes in rows and have row 1 &amp; 3 marked as odd, and row 2 marked as even (I'm expected to have many more rows with the real project.)</p>
  
  <p>Thus, I thought I should be able to use the fn:position() function. Unfortunately, the position returned is the one of the original nodes, not the resulting sorted nodes. Is there a way to fix that problem?</p>
  
  <p>There is a sample XSLT that exposes the problem:</p>
  
  <pre><code>&lt;?xml version="1.0"?&gt;
  &lt;xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
    &lt;xsl:template match="body"&gt;
      &lt;xsl:apply-templates&gt;
        &lt;xsl:sort select="@priority" data-type="number"/&gt;
      &lt;/xsl:apply-templates&gt;
    &lt;/xsl:template&gt;
    &lt;xsl:template match="body/box"&gt;
  &lt;div class="box"&gt;
  Box[&lt;xsl:value-of select="count(preceding-sibling::box) + 1" /&gt;,&lt;xsl:value-of select="position()"/&gt;] = (&lt;xsl:value-of select="@priority"/&gt;)
    &lt;xsl:copy-of select="title"/&gt;&lt;/div&gt;
    &lt;/xsl:template&gt;
  &lt;/xsl:stylesheet&gt;
  </code></pre>
  
  <p>And there is an example of input. TWO should appear first, then THREE and finally ONE.</p>
  
  <pre><code>&lt;?xml version="1.0"?&gt;
  &lt;body&gt;
    &lt;box priority="103"&gt;
      &lt;title&gt;This is box ONE&lt;/title&gt;
    &lt;/box&gt;
    &lt;box priority="1"&gt;
      &lt;title&gt;This is box TWO&lt;/title&gt;
    &lt;/box&gt;
    &lt;box priority="12"&gt;
      &lt;title&gt;This is box THREE&lt;/title&gt;
    &lt;/box&gt;
  &lt;/body&gt;
  </code></pre>
  
  <p>Yet I'd expect position() to be 1, 2, and 3... but this is the output:</p>
  
  <pre><code>&lt;div class="box"&gt;
  Box[2,4] = (1)
    &lt;title&gt;This is box TWO&lt;/title&gt;
  &lt;/div&gt;
  &lt;div class="box"&gt;
  Box[3,6] = (12)
    &lt;title&gt;This is box THREE&lt;/title&gt;
  &lt;/div&gt;
  &lt;div class="box"&gt;
  Box[1,2] = (103)
    &lt;title&gt;This is box ONE&lt;/title&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p>The second number inside the Box square brackets is the position(). I was expected 1, 2, 3. But as we can see, we get 4, 6, 2 which is the position of the node in the original document (I'm not too sure why it's x2 though, when I tested with an xsl:for-each tag, it was 2, 3, and 1 instead.)</p>
  
  <p>I tested with xmlpatterns (Qt 4.7) and xsltproc (libxml2, this should use version 1.0, the code is compatible to 1.0) and both return the same numbers.</p>
  
  <p>So... is that a limit of XSLT, or is that a bug in those two XSLT implementations?!</p>
  
  <p><strong>Update May 27, 2012</strong></p>
  
  <p>It was determined that QXmlQuery (xmlpatterns) is a broken parser in that specific case. The position() must be computed using something similar to <code>count(preceding-sibling::box) + 1</code> instead of the correct index in the running for-each or template sequence.</p>