title: Sorting in XSL apply-templates nodes using other nodes from a variable (XSLT 1.0)
body: <p><strong>How to sort <code>&lt;foo name="..."/&gt;</code> nodes from $foo using their corresponding node order from $bar?</strong></p>
  
  <p><s>Partial solution (Mark Veenstra)</p>
  
  <pre><code>&lt;xsl:for-each select="$list-resources"&gt;
      &lt;xsl:apply-templates select="$building-resources[@name = current()/@name]"&gt;
          &lt;xsl:with-param name="param" select="$some-value"/&gt;
      &lt;/xsl:apply-templates&gt;
  &lt;/xsl:for-each&gt;
  </code></pre>
  
  <p>New problem (see edit at the end of the question):</p>
  
  <p><strong>How to retrieve the position in the whole sorted node set of each $building-resources node?</strong>
  </s></p>
  
  <hr>
  
  <h2><strong>TL;DR answer</strong></h2>
  
  <ul>
  <li><p>The <code>&lt;xsl:sort/&gt;</code> has an attribute, <code>@data-type</code>, to specify the type of data in the <code>@select</code> node. <em>Default is "text". Since I compare numbers, I must set</em> <code>@data-type="number"</code>. Else, the text comparison fails when it comes to compare 9 and 10.</p></li>
  <li><p><code>&lt;xsl:sort select="count($bar[@name = current()/@name]/preceding-sibling::*)" data-type="number"/&gt;</code></p></li>
  <li><p>In <code>&lt;xsl:sort/&gt;</code>, <code>current()</code> refers to the currently sorted node (not to the <code>&lt;xsl:template/&gt;</code> current node)</p></li>
  </ul>
  
  <p>Thanks to michael.hor257k</p>
  
  <hr>
  
  <h2><strong>Complete Answer</strong></h2>
  
  <p><strong>Code</strong>
      
          
          </p>
  
  <pre><code>    &lt;!-- Resource "instances" to order, using $list-resources --&gt;
      &lt;xsl:variable name="building-resources"
          select="document('building.xml')/building/resource"/&gt;
  
      &lt;result&gt;
          &lt;!-- Apply templates to the resource instances --&gt;
          &lt;xsl:apply-templates select="$building-resources"&gt;
              &lt;!-- Sort using the nodes order from the resources list --&gt;
              &lt;!-- Don't forget the @data-type: we're comparing NUMBERS not TEXTS --&gt;
              &lt;xsl:sort
                  select="count($list-resources[@name = current()/@name]/preceding-sibling::*)"
                  data-type="number"/&gt;
          &lt;/xsl:apply-templates&gt;
      &lt;/result&gt;
  &lt;/xsl:template&gt;
  
  &lt;!-- Template to apply for each resource of $building-resources --&gt;
  &lt;xsl:template match="ressource"&gt;
      &lt;!-- position() refers to the node position in $building-resources
      because we used $building-resources as @select value
      of the apply-templates --&gt;
      &lt;output position="{position()}"&gt;
          &lt;xsl:value-of select="."/&gt;
      &lt;/output&gt;
  &lt;/xsl:template&gt;
  </code></pre>
  
  <p><em>Inputs</em></p>
  
  <p>list-resources.xml</p>
  
  <pre><code>&lt;resources&gt;
      &lt;resource name="wood"/&gt;
      &lt;resource name="stone"/&gt;
      &lt;resource name="gold"/&gt;
  &lt;/resources&gt;
  </code></pre>
  
  <p>building-resources.xml</p>
  
  <pre><code>&lt;building&gt;
      &lt;resource name="stone"/&gt;
      &lt;resource name="gold"/&gt;
      &lt;resource name="stone"/&gt;
      &lt;resource name="wood"/&gt;
      &lt;resource name="wood"/&gt;
  &lt;/building&gt;
  </code></pre>
  
  <p><em>Output</em></p>
  
  <pre><code>&lt;result&gt;
      &lt;output position="1"&gt;wood&lt;/output&gt;
      &lt;output position="2"&gt;wood&lt;/output&gt;
      &lt;output position="3"&gt;stone&lt;/output&gt;
      &lt;output position="4"&gt;stone&lt;/output&gt;
      &lt;output position="5"&gt;gold&lt;/output&gt;
  &lt;/result&gt;
  </code></pre>
  
  <hr>
  
  <h2><strong>Original question</strong></h2>
  
  <p><strong>Sorting</strong></p>
  
  <p>I have two XML documents:</p>
  
  <p>A list of resources (<code>list-resources.xml</code>, like a "class" list):</p>
  
  <pre><code>&lt;resources&gt;
      &lt;resource name="wood"/&gt;
      &lt;resource name="stone"/&gt;
      &lt;resource name="gold"/&gt;
  &lt;/resources&gt;
  </code></pre>
  
  <p>And resources inside a building (<code>buildings.xml</code>, like "objects" list):</p>
  
  <pre><code>&lt;building&gt;
      &lt;resource name="stone"/&gt;
      &lt;resource name="gold"/&gt;
      &lt;resource name="stone"/&gt;
      &lt;resource name="wood"/&gt;
      &lt;resource name="wood"/&gt;
  &lt;/building&gt;
  </code></pre>
  
  <p>I want to order the <code>&lt;resource/&gt;</code> nodes from <code>&lt;building/&gt;</code> so it matches the <code>&lt;resource/&gt;</code> order from <code>&lt;resources/&gt;</code>. This is the desired output:</p>
  
  <pre><code>&lt;result&gt;
      &lt;output position="1"&gt;wood&lt;/output&gt;
      &lt;output position="2"&gt;wood&lt;/output&gt;
      &lt;output position="3"&gt;stone&lt;/output&gt;
      &lt;output position="4"&gt;stone&lt;/output&gt;
      &lt;output position="5"&gt;gold&lt;/output&gt;
  &lt;/result&gt;
  </code></pre>
  
  <p>To do so, I have two node-sets in a XSL:</p>
  
  <pre><code>&lt;xsl:variable name="building-resources" select="building/resource"/&gt;
  &lt;xsl:variable name="list-resources" select="resources/resource"/&gt;
  </code></pre>
  
  <p>And I use an XSL apply-templates to treat nodes from <code>$building-resources</code>:</p>
  
  <pre><code>&lt;xsl:apply-templates select="$building-resources"&gt;
      &lt;xsl:with-param name="some-param" select="$variable-from-somewhere"/&gt;
  &lt;/xsl:apply-templates&gt;
  </code></pre>
  
  <p>Let's say the applied templates is ok. My currently not-sorted result is:</p>
  
  <pre><code>&lt;result&gt;
      &lt;output position="1"&gt;stone&lt;/output&gt;
      &lt;output position="2"&gt;gold&lt;/output&gt;
      &lt;output position="3"&gt;stone&lt;/output&gt;
      &lt;output position="4"&gt;wood&lt;/output&gt;
      &lt;output position="5"&gt;wood&lt;/output&gt;
  &lt;/result&gt;
  </code></pre>
  
  <p>Now, I added a <code>&lt;xsl:sort/&gt;</code> element to sort my nodes from <code>$building-resources</code>, but I don't know what to put inside its <code>@select</code>...</p>
  
  <pre><code>&lt;xsl:apply-templates select="$building-resources"&gt;
      &lt;xsl:sort select="what-to-put-here"/&gt;
      &lt;xsl:with-param name="some-param" select="$variable-from-somewhere"/&gt;
  &lt;/xsl:apply-templates&gt;
  </code></pre>
  
  <p>I tried the following XPath expression:</p>
  
  <pre><code>count($list-ressources[@name = current()/@name]/preceding-sibling::*)
  </code></pre>
  
  <p><s>But inside this XPath, <code>current()</code> refers to the node treated by the <code>&lt;xsl:template/&gt;</code> where <code>&lt;xsl:apply-templates/&gt;</code> is.
  So, instead of <code>current()</code>, </s>
  But this doesn't work, the result is not correctly sorted.
  I would mean <em>"the node the <code>&lt;xsl:sort/&gt;</code> process is currently treating"</em> <em>(edit: this is actually exactly what current() does!)</em> inside my XPath brackets <code>$list-resources[]</code>. How do I do so?</p>
  
  <hr>
  
  <p><strong>Get the sorted position</strong></p>
  
  <p>Since I simplified the code, I forgot something... Mark Veenstra's solution raised up a problem.</p>
  
  <p>In the applied template (the template that generates the <code>&lt;output/&gt;</code> node), I use <code>position()</code> to get the position of the node the template is applied on:</p>
  
  <pre><code>&lt;xsl:template match="resource"&gt;
      &lt;xsl:variable name="position" select="position()"/&gt;
      &lt;output position="{$position}"&gt;
          &lt;xsl:value-of select="@name"/&gt;
      &lt;/output&gt;
  &lt;/xsl:template&gt;
  </code></pre>
  
  <p>This works well as long as I do only "one" apply-templates (hence the <code>position()</code> inside the this applied template holds the position of the node in the sorted list). But if I apply Mark's solution (note that <code>current()</code> inside the <code>&lt;xsl:sort/&gt;</code> now refers to the node from the <code>&lt;xsl:for-each/&gt;</code> aka from $liste-resources):</p>
  
  <pre><code>&lt;xsl:for-each select="$list-resources"&gt;
      &lt;xsl:apply-templates select="$building-resources[@name = current()/@name]"&gt;
          &lt;xsl:with-param name="param" select="$some-value"/&gt;
      &lt;/xsl:apply-templates&gt;
  &lt;/xsl:for-each&gt;
  </code></pre>
  
  <p>Then the <code>position()</code> inside the applied template refers to the position of the node in the <em>partial</em> node set ($building-resources[@name = current()/@name]).</p>
  
  <p>How to fix that?</p>