我希望在xsl中有一个键值映射,因此定义了一个具有xml片段的变量,但是稍后当我尝试访问变量中的xml节点时,我得到一个错误,即xpath xpression的类型无法解析
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:variable name="map">
<map>
<entry key="key-1">value1</entry>
<entry key="key-2">value2</entry>
<entry key="key-3">value3</entry>
</map>
</xsl:variable>
<output>
<xsl:value-of select="$map/entry[@key='key-1']"/>
</output>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:37)
使用XSLT 2.0,以下解决方案有效:
<xsl:variable name="map">
<entry key="key-1">value1</entry>
<entry key="key-2">value2</entry>
<entry key="key-3">value3</entry>
</xsl:variable>
<xsl:template match="/">
<output>
<xsl:value-of select="$map/entry[@key='key-1']"/>
</output>
</xsl:template>
您不能在XSLT 1.0中的XPath表达式中使用结果树片段,但fn:document()
可以检索映射值。 similar question的答案可以在这里使用:。
<xsl:value-of select="document('')//xsl:variable[@name='map']/map/entry[@key='key-1']"/>
中所述
document('')
指的是根节点 样式表;那个树 样式表的表示是 与XML完全相同 包含样式表的文档是 最初的源文件。
但是,您不需要使用xsl:variable
。您可以直接在xsl:stylesheet
下指定您的地图节点,但您必须记住顶级元素必须具有非空名称空间URI:
<xsl:stylesheet
version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="some.uri" exclude-result-prefixes="my">
<my:map>
<entry key="key-1">value1</entry>
<entry key="key-2">value2</entry>
<entry key="key-3">value3</entry>
</my:map>
<xsl:template match="/">
<output>
<xsl:value-of select="document('')/*/my:map/entry[@key='key-1']"/>
</output>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:6)
您可以解决使用XSLT 1.0缺少支持将变量的内容用作节点集的问题。您将不得不依赖解析器制造商添加的扩展。例如,Microsoft提供了一个解决此问题的函数:node-set()
您的XSL将如下所示:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:template match="/">
<xsl:variable name="map">
<map>
<entry key="key-1">value1</entry>
<entry key="key-2">value2</entry>
<entry key="key-3">value3</entry>
</map>
</xsl:variable>
<output>
<xsl:value-of select="msxsl:node-set($map)/map/entry[@key='key-1']"/>
</output>
</xsl:template>
</xsl:stylesheet>
请注意命名空间和msxsl-prefix。这仅适用于基于Microsoft解析器的应用程序(例如:Internet Explorer使用它,以及.NET)。 其他解析器可能有也可能没有这样的扩展(例如,Saxxon,但它的命名略有不同)。但是,它取决于XSLT 2.0,因为它在XSLT 1.0中可以正常工作,而Microsoft尚未在其XML库中支持XSLT 2.0(除非他们最近添加了它)。
根据您使用的解析器,上述内容可能适用于您,否则Per T的答案对您更有帮助。
答案 2 :(得分:5)
在XSLT 3.0工作草案中,提出了一种新的XPath项(map),请参阅maps in XSLT 3.0 WD Spec。
因此,如果您的XSLT处理器支持3.0和地图(例如Saxon 9.4),您可以使用以下代码:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="3.0">
<xsl:output indent="yes"/>
<xsl:template match="/">
<xsl:variable name="map" select="
map {
'key-1' := 'value1',
'key-2' := 'value2',
'key-3' := 'value3' }">
</xsl:variable>
<output>
<xsl:value-of select="
$map('key-1') || ', ' || $map('key-2') || ', ' || $map('key-3')"/>
</output>
</xsl:template>
</xsl:stylesheet>