xml XSLT:在 XSLT 中创建地图
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3626118/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
XSLT : Creating a Map in XSLT
提问by keshav84
I want to have a key value map in xsl and so defined a variable which has an xml fragment, but later when I try to access the xml nodes in the variable I get an error that type of the xpath xpression cannot be resolved.
我想在 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>
回答by Per T
XSLT 2.0
XSLT 2.0
Using XSLT 2.0, the following solution works:
使用 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
XSLT 1.0
You cannot use a result tree fragment in a XPath expression in XSLT 1.0, but fn:document()can retrieve map values. An answer to a similar questionwill work here:.
您不能在 XSLT 1.0 的 XPath 表达式中使用结果树片段,但fn:document()可以检索映射值。类似问题的答案将在这里工作:。
<xsl:value-of select="document('')//xsl:variable[@name='map']/map/entry[@key='key-1']"/>
As described in the XSLT 1.0 specification:
document('')refers to the root node of the stylesheet; the tree representation of the stylesheet is exactly the same as if the XML document containing the stylesheet was the initial source document.
document('')指样式表的根节点;样式表的树表示与包含样式表的 XML 文档是初始源文档完全相同。
However, you don't need to use xsl:variablefor this. You could specify your map node directly under xsl:stylesheet, but you must remember that a top level elements must have a non null namespace URI:
但是,您不需要为此使用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>
回答by Rob
You can sort of work around XSLT 1.0 missing support for using the variable's contents as a node set. You'll have to rely on extensions added by the parser's maker. For example, Microsoft has offered a function to work around this: node-set()
您可以解决 XSLT 1.0 缺少将变量的内容用作节点集的支持。您将不得不依赖解析器制造商添加的扩展。例如,微软提供了一个函数来解决这个问题:node-set()
Your XSL will look like this:
您的 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>
Notice the namespace and the msxsl-prefix here. This will only work in applications based on Microsoft's parser (for example: Internet Explorer utilizes it, as well as .NET). Other parsers may or may not have such an extension (Saxxon does, for example, but it's named a bit differently). But, it eliminates depending on XSLT 2.0, as this will work fine in XSLT 1.0 and Microsoft has yet to support XSLT 2.0 in their XML library (unless they've added it recently).
注意这里的命名空间和 msxsl 前缀。这仅适用于基于 Microsoft 解析器的应用程序(例如:Internet Explorer 以及 .NET 使用它)。其他解析器可能有也可能没有这样的扩展(例如,Saxxon 有,但它的命名有点不同)。但是,它消除了对 XSLT 2.0 的依赖,因为这在 XSLT 1.0 中可以正常工作,而且 Microsoft 尚未在其 XML 库中支持 XSLT 2.0(除非他们最近添加了它)。
Depending on the parser you're using, the above may work fine for you, otherwise Per T's answer is better for you.
根据您使用的解析器,上述内容可能适合您,否则 Per T 的答案对您更好。
回答by j_maly
In XSLT 3.0 Working Draft, a new kind of XPath item (map) is proposed, see maps in XSLT 3.0 WD Spec.
在 XSLT 3.0 Working Draft 中,提出了一种新的 XPath 项(映射),请参阅XSLT 3.0 WD Spec 中的映射。
So, if your XSLT processor supports 3.0 and maps (e.g. Saxon 9.4), you can use the following code:
因此,如果您的 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>

