title: XSLT 2.0 External lookup using key() and document()
body: <p>I'm pulling what's left of my hair out trying to get a simple external lookup working using Saxon 9.1.0.7.</p>
  
  <p>I have a simple source file <strong>dummy.xml</strong>:</p>
  
  <pre><code>&lt;something&gt;
     &lt;monkey&gt;
        &lt;genrecode&gt;AAA&lt;/genrecode&gt;
     &lt;/monkey&gt;
     &lt;monkey&gt;
        &lt;genrecode&gt;BBB&lt;/genrecode&gt;
     &lt;/monkey&gt;
     &lt;monkey&gt;
        &lt;genrecode&gt;ZZZ&lt;/genrecode&gt;
     &lt;/monkey&gt;
     &lt;monkey&gt;
        &lt;genrecode&gt;ZER&lt;/genrecode&gt;
     &lt;/monkey&gt;
  &lt;/something&gt;
  </code></pre>
  
  <hr>
  
  <p>Then the lookup file is <strong>GenreSet_124.xml</strong>:</p>
  
  <pre><code>&lt;GetGenreMappingObjectsResponse&gt;
     &lt;tuple&gt;
        &lt;old&gt;
           &lt;GenreMapping DepartmentCode="AAA"
                         DepartmentName="AND - NEWS AND CURRENT AFFAIRS"
                         Genre="10 - NEWS"/&gt;
        &lt;/old&gt;
     &lt;/tuple&gt;
     &lt;tuple&gt;
        &lt;old&gt;
           &lt;GenreMapping DepartmentCode="BBB"
                         DepartmentName="AND - NEWS AND CURRENT AFFAIRS"
                         Genre="11 - NEWS"/&gt;
        &lt;/old&gt;
     &lt;/tuple&gt;
  
     ... lots more
  &lt;/GetGenreMappingObjectsResponse&gt;
  </code></pre>
  
  <hr>
  
  <p>What I'm trying to achieve is simply to get hold of the "Genre" value based on the "DepartmentCode" value.</p>
  
  <p>So my XSL looks like:</p>
  
  <pre><code>...
  &lt;!-- Set up the genre lookup key --&gt;
  &lt;xsl:key name="genre-lookup" match="GenreMapping" use="@DepartmentCode"/&gt;
  
  
  &lt;xsl:variable name="lookupDoc" select="document('GenreSet_124.xml')"/&gt;
  
  &lt;xsl:template match="/something"&gt;
  &lt;stuff&gt;
     &lt;xsl:for-each select="monkey"&gt;
        &lt;Genre&gt;
  
         &lt;xsl:apply-templates select="$lookupDoc"&gt; 
           &lt;xsl:with-param name="curr-label" select="genrecode"/&gt; 
        &lt;/xsl:apply-templates&gt;
  
        &lt;/Genre&gt;
     &lt;/xsl:for-each&gt;
  &lt;/stuff&gt;
  &lt;/xsl:template&gt;
  
  &lt;xsl:template match="GetGenreMappingObjectsResponse"&gt;
     &lt;xsl:param name="curr-genrecode"/&gt; 
  
     &lt;xsl:value-of select="key('genre-lookup', $curr-genrecode)/@Genre"/&gt;
  
  &lt;/xsl:template&gt;
  </code></pre>
  
  <p>...</p>
  
  <hr>
  
  <p>The issue that I have is that I get nothing back. I currently just get </p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;stuff&gt;
     &lt;Genre/&gt;
     &lt;Genre/&gt;
     &lt;Genre/&gt;
     &lt;Genre/&gt;
  &lt;/stuff&gt;
  </code></pre>
  
  <p>I have moved all the lookup data to be attributes of GenreMapping, previously as child elements of GenreMapping whenever I entered the template match="GetGenreMappingObjectsResponse" it would just print out all text from every GenreMapping (DepartmentCode, DepartmentName, Genre)!</p>
  
  <p>I can't for the life of me figure out what I am doing wrong. Any helpo/suggestions would be greatly appreciated.</p>
  
  <p>PLease find the current actual XSLT listing:</p>
  
  <pre><code>&lt;?xml version="1.0"?&gt;
  &lt;xsl:stylesheet version="2.0"
                  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                  xmlns:xs="http://www.w3.org/2001/XMLSchema"&gt;
  
  &lt;!-- Define the global parameters --&gt;
  &lt;xsl:param name="TransformationID"/&gt;
  &lt;xsl:param name="TransformationType"/&gt;
  
  &lt;!-- Specify that XML is the desired output type --&gt; 
  &lt;xsl:output method="xml" encoding="UTF-8" indent="yes"/&gt;
  
  &lt;!-- Set up the genre matching capability --&gt;
  &lt;xsl:key name="genre-lookup" match="GenreMapping" use="@DepartmentCode"/&gt;
  
  &lt;xsl:variable name="documentPath"&gt;&lt;xsl:value-of select="concat('GenreSet_',$TransformationID,'.xml')"/&gt;&lt;/xsl:variable&gt;
  &lt;xsl:variable name="lookupDoc" select="document($documentPath)"/&gt;
  
  &lt;!-- Start the first match on the Root level --&gt;
  &lt;xsl:template match="/something"&gt;
  &lt;stuff&gt;
     &lt;xsl:for-each select="monkey"&gt;
        &lt;Genre&gt;
        &lt;xsl:apply-templates select="$lookupDoc/*"&gt;
           &lt;xsl:with-param name="curr-genrecode" select="string(genrecode)"/&gt;
        &lt;/xsl:apply-templates&gt;
        &lt;/Genre&gt;
     &lt;/xsl:for-each&gt;
  &lt;/stuff&gt;
  &lt;/xsl:template &gt;
  
  &lt;xsl:template match="GetGenreMappingObjectsResponse"&gt;
     &lt;xsl:param name="curr-genrecode"/&gt;
     &lt;xsl:value-of select="key('genre-lookup', $curr-genrecode, $lookupDoc)/@Genre"/&gt;
  &lt;/xsl:template&gt;
  &lt;/xsl:stylesheet&gt;
  </code></pre>
  
  <p>The TransformationID is alway 124 (so the correct lookup file is opened. The Type is just a name that I am currently not using but intending to.</p>