The key to your problem is as follows: key() function selects matching nodes from a document the context node belongs to. In your case it's /categories/category/element element. If you want to select nodes from original document you need to switch context. Usually it's done using xsl:for-each:
<xsl:variable name="root" select="/"/>
<xsl:for-each select="document('categories.xml')/categories/category"> <tr bgcolor="silver"> <td><xsl:value-of select="@name" /> </td> </tr> <xsl:for-each select="element"> <tr><td>
<xsl:variable name="element-name" select="@name"/>
<xsl:for-each select="$root"> <xsl:apply-templates select="key('animal-name', $element-name)" mode="test"/>
</xsl:for-each> </td> </tr> </xsl:for-each> </xsl:for-each>
Sure, but then you need to iterate over source elements, not categories - just select each element having no category: