在 XSLT 1.0 中,如何使用键和文档 ('') 在 XSLT 中嵌入的 XML 数据上创建查找函数?
In XSLT 1.0 how to create a lookup function on XML data embedded in the XSLT using key and document('')?
我的具体需要是在给定特定字体大小的情况下查找行高,但我正在寻求学习创建 lookups/a 特定映射的一般技术。
我认为可以将 XML 嵌入 XSLT 文档本身(因此它可以独立工作)并使用 document('') 函数在其上构建一个密钥以引用当前的 XSLT,一些东西像这样:
<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"/>
之后,我应该可以使用键函数查找行高:
<xsl:value-of select="key('lookup.font-metrics.line-height',$font-size)"/>
...但是我收到以下错误消息:
XPath error : Invalid expression
//document('')//xsl:variable[@name='data.font-metrics.line-height'])/line-height/text()
^
我认为这里有几个问题:
- 文档功能的使用
- 按键功能的使用
- 最好的嵌入方法是什么XML?在变量中?
也可能有完全不同的解决方法。
非常感谢您的帮助!
在 XSLT 1.0 中,key() 函数仅在当前文档的上下文中起作用(在 XSLT 2.0 中,它有第三个参数,允许您 select 上下文)。为了在另一个文档中的节点上使用键,您必须首先将上下文切换到该文档 - 例如:
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>
结果
<?xml version="1.0" encoding="UTF-8"?>
<output>
<lookup>16</lookup>
</output>
请注意,xsl:key
元素并未在此开关中发挥作用,可以用更简单的术语进行定义。
这意味着 <xsl:key>
在 XSLT 引擎首次到达关键定义元素时未(匹配和)编译,而是在 XSLT 引擎遇到 第一个 XPath key() 函数。只有在这个时候才能创建密钥,因为只有这样上下文才知道。
...一种惰性执行...
MOREOVER 一个键可以应用于多个文档,因此如果要转换的 XML 文档包含以下 XML:
<?xml version="1.0" encoding="UTF-8"?>
<fmxmlsnippet type="LayoutObjectList">
<Layout enclosingRectTop ="46.0000000" enclosingRectLeft ="46.0000000" enclosingRectBottom ="171.0000000" enclosingRectRight ="366.0000000">
<line-height font-size="14">18 in XML file</line-height>
…
然后是下面的XSLT(添加到上面原来的XSLT):
<xsl:comment>
<xsl:for-each select="document('')">
<!-- apply the key to the XSLT document -->
<xsl:value-of select="key('lookup.font-metrics.line-height','14')"/>
</xsl:for-each>
</xsl:comment>
<xsl:comment>
<!-- apply the key to the XML document -->
<xsl:value-of select="key('lookup.font-metrics.line-height','14')"/>
</xsl:comment>
将创建以下输出:
<!--16-->
<!--18 in XML file-->
因此 key 函数不是对先前构建的静态索引的引用,而是 - 结合 for-each-document('') 技巧 - 正是我正在寻找的:一个可以是在 XML 个节点上使用,无论它们在哪里!
不错。
我的具体需要是在给定特定字体大小的情况下查找行高,但我正在寻求学习创建 lookups/a 特定映射的一般技术。
我认为可以将 XML 嵌入 XSLT 文档本身(因此它可以独立工作)并使用 document('') 函数在其上构建一个密钥以引用当前的 XSLT,一些东西像这样:
<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"/>
之后,我应该可以使用键函数查找行高:
<xsl:value-of select="key('lookup.font-metrics.line-height',$font-size)"/>
...但是我收到以下错误消息:
XPath error : Invalid expression
//document('')//xsl:variable[@name='data.font-metrics.line-height'])/line-height/text()
^
我认为这里有几个问题:
- 文档功能的使用
- 按键功能的使用
- 最好的嵌入方法是什么XML?在变量中?
也可能有完全不同的解决方法。
非常感谢您的帮助!
在 XSLT 1.0 中,key() 函数仅在当前文档的上下文中起作用(在 XSLT 2.0 中,它有第三个参数,允许您 select 上下文)。为了在另一个文档中的节点上使用键,您必须首先将上下文切换到该文档 - 例如:
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>
结果
<?xml version="1.0" encoding="UTF-8"?>
<output>
<lookup>16</lookup>
</output>
请注意,xsl:key
元素并未在此开关中发挥作用,可以用更简单的术语进行定义。
这意味着 <xsl:key>
在 XSLT 引擎首次到达关键定义元素时未(匹配和)编译,而是在 XSLT 引擎遇到 第一个 XPath key() 函数。只有在这个时候才能创建密钥,因为只有这样上下文才知道。
...一种惰性执行...
MOREOVER 一个键可以应用于多个文档,因此如果要转换的 XML 文档包含以下 XML:
<?xml version="1.0" encoding="UTF-8"?>
<fmxmlsnippet type="LayoutObjectList">
<Layout enclosingRectTop ="46.0000000" enclosingRectLeft ="46.0000000" enclosingRectBottom ="171.0000000" enclosingRectRight ="366.0000000">
<line-height font-size="14">18 in XML file</line-height>
…
然后是下面的XSLT(添加到上面原来的XSLT):
<xsl:comment>
<xsl:for-each select="document('')">
<!-- apply the key to the XSLT document -->
<xsl:value-of select="key('lookup.font-metrics.line-height','14')"/>
</xsl:for-each>
</xsl:comment>
<xsl:comment>
<!-- apply the key to the XML document -->
<xsl:value-of select="key('lookup.font-metrics.line-height','14')"/>
</xsl:comment>
将创建以下输出:
<!--16-->
<!--18 in XML file-->
因此 key 函数不是对先前构建的静态索引的引用,而是 - 结合 for-each-document('') 技巧 - 正是我正在寻找的:一个可以是在 XML 个节点上使用,无论它们在哪里!
不错。