My specific need is to lookup line-heights given a particular font-size, but I am seeking to learn a general technique of creating lookups/a specific mapping.
I think it is possible to embed XML in the XSLT document itself (so it can work standalone) and build a key on it using the document('') function to reference the current XSLT, something like this:
<xsl:variable name="data.font-metrics.line-height">
<line-height font-size="11">12</line-height>
<line-height font-size="12">14</line-height>
<line-height font-size="13">15</line-height>
<line-height font-size="14">16</line-height>
<line-height font-size="15">17</line-height>
<line-height font-size="16">18</line-height>
<line-height font-size="17">20</line-height>
<line-height font-size="18">21</line-height>
</xsl:variable>
<xsl:key name="lookup.font-metrics.line-height" match="document('')//xsl:variable[@name='data.font-metrics.line-height'])/line-height" use="@font-size"/>
After that, I should be able to lookup a line height using the key function:
<xsl:value-of select="key('lookup.font-metrics.line-height',$font-size)"/>
...however I am getting the following error message:
XPath error : Invalid expression
//document('')//xsl:variable[@name='data.font-metrics.line-height'])/line-height/text()
^
I think several problems are coming together here:
There may also be a completely different solution to the problem.
I would be very grateful of your help!
In XSLT 1.0, the key()
function works only in the context of the current document (in XSLT 2.0 it has a third argument, allowing you to select the context). In order to use the key on nodes in another document, you must first switch the context to that document - for example:
XSLT 1.0
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:variable name="data.font-metrics.line-height">
<line-height font-size="11">12</line-height>
<line-height font-size="12">14</line-height>
<line-height font-size="13">15</line-height>
<line-height font-size="14">16</line-height>
<line-height font-size="15">17</line-height>
<line-height font-size="16">18</line-height>
<line-height font-size="17">20</line-height>
<line-height font-size="18">21</line-height>
</xsl:variable>
<xsl:key name="lookup.font-metrics.line-height" match="line-height" use="@font-size"/>
<xsl:template match="/">
<xsl:param name="font-size" select="14"/>
<output>
<!-- other nodes -->
<!-- switch context to the stylesheet itself in order to use the key -->
<xsl:for-each select="document('')">
<lookup>
<xsl:value-of select="key('lookup.font-metrics.line-height', $font-size)"/>
</lookup>
</xsl:for-each>
<!-- more nodes -->
</output>
</xsl:template>
</xsl:stylesheet>
Result
<?xml version="1.0" encoding="UTF-8"?>
<output>
<lookup>16</lookup>
</output>
Note that the xsl:key
element is not playing a part in this switch and can be defined in much simpler terms.