如何高效运用XSLT 3.0的map和array功能?
- 内容介绍
- 相关推荐
本文共计839个文字,预计阅读时间需要4分钟。
直接说结论:
真正可用的是:
-
map { "key1": "val1", "key2": 42 }—— 字面量构造 map -
array { 1, 2, 3 }—— 字面量构造 array -
map:merge( (map { "a": 1 }, map { "b": 2 }) )—— 来自map命名空间的实用函数(需声明xmlns:map="http://www.w3.org/2005/xpath-functions/map") -
array:for-each($arr, function($x) { $x + 1 })—— 注意:这是array:for-each,不是map();它返回新 array,行为接近 map,但函数名固定
怎么安全创建和访问 map/array?
XSLT 3.0 支持 map 和 array 类型,但必须确保处理器支持(如 Saxon HE 10+、Saxon PE/EE、BaseX 10+),且启用 XPath 3.1 模式(version="3.1")。
常见写法示例:
<xsl:stylesheet version="3.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:map="http://www.w3.org/2005/xpath-functions/map" xmlns:array="http://www.w3.org/2005/xpath-functions/array"> <p><xsl:template match="/"> <!-- 构造一个 map --> <xsl:variable name="user" as="map(*)" select="map { 'name': 'Alice', 'age': 30, 'active': true() }"/></p><pre class='brush:php;toolbar:false;'><!-- 访问 key --> <xsl:value-of select="$user?name"/> <!-- → Alice --> <!-- 构造 array --> <xsl:variable name="scores" as="array(*)" select="array { 85, 92, 78 }"/> <!-- 取第 2 个元素(索引从 1 开始!)--> <xsl:value-of select="$scores?2"/> <!-- → 92 --> <!-- 用 array:for-each 实现类似 map 的转换 --> <xsl:variable name="doubled" as="array(*)" select="array:for-each($scores, function($x) { $x * 2 })"/>
</xsl:template> </xsl:stylesheet>
常见报错和坑点
以下错误几乎都源于类型或命名空间缺失:
-
XPST0003或XPDY0002:未声明xmlns:map/xmlns:array,或 XSLT 版本不是3.1 -
XPTY0004:对非 map 变量使用?key语法(比如变量类型是xs:string却写$x?name) -
FORG0006:用?0或负数索引访问 array(XPath array 索引从 1 开始) - 空 map/array 被误判为
():注意map {} eq ()是false();要用map:size($m) = 0判空
替代方案:什么时候该用 XSLT 3.0 map/array?
它们适合做「结构化中间数据」,而非通用循环工具。真实场景中更常用:
- 把 XML 节点集转成 map 做快速查找(比如 ID → 元素映射)
- 用
array:for-each+array:filter处理分组后的一维结果(比嵌套xsl:for-each更紧凑) - 配合
xsl:iterate实现状态累积(例如计数、拼接字符串) - 避免频繁调用
key()或//—— 预建 map 查表更快
如果你只是想“对每个节点执行一个函数”,老老实实用 xsl:for-each 或 xsl:iterate 更稳;map/array 的价值在于表达「键值关系」和「有序集合语义」,不是语法糖。
本文共计839个文字,预计阅读时间需要4分钟。
直接说结论:
真正可用的是:
-
map { "key1": "val1", "key2": 42 }—— 字面量构造 map -
array { 1, 2, 3 }—— 字面量构造 array -
map:merge( (map { "a": 1 }, map { "b": 2 }) )—— 来自map命名空间的实用函数(需声明xmlns:map="http://www.w3.org/2005/xpath-functions/map") -
array:for-each($arr, function($x) { $x + 1 })—— 注意:这是array:for-each,不是map();它返回新 array,行为接近 map,但函数名固定
怎么安全创建和访问 map/array?
XSLT 3.0 支持 map 和 array 类型,但必须确保处理器支持(如 Saxon HE 10+、Saxon PE/EE、BaseX 10+),且启用 XPath 3.1 模式(version="3.1")。
常见写法示例:
<xsl:stylesheet version="3.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:map="http://www.w3.org/2005/xpath-functions/map" xmlns:array="http://www.w3.org/2005/xpath-functions/array"> <p><xsl:template match="/"> <!-- 构造一个 map --> <xsl:variable name="user" as="map(*)" select="map { 'name': 'Alice', 'age': 30, 'active': true() }"/></p><pre class='brush:php;toolbar:false;'><!-- 访问 key --> <xsl:value-of select="$user?name"/> <!-- → Alice --> <!-- 构造 array --> <xsl:variable name="scores" as="array(*)" select="array { 85, 92, 78 }"/> <!-- 取第 2 个元素(索引从 1 开始!)--> <xsl:value-of select="$scores?2"/> <!-- → 92 --> <!-- 用 array:for-each 实现类似 map 的转换 --> <xsl:variable name="doubled" as="array(*)" select="array:for-each($scores, function($x) { $x * 2 })"/>
</xsl:template> </xsl:stylesheet>
常见报错和坑点
以下错误几乎都源于类型或命名空间缺失:
-
XPST0003或XPDY0002:未声明xmlns:map/xmlns:array,或 XSLT 版本不是3.1 -
XPTY0004:对非 map 变量使用?key语法(比如变量类型是xs:string却写$x?name) -
FORG0006:用?0或负数索引访问 array(XPath array 索引从 1 开始) - 空 map/array 被误判为
():注意map {} eq ()是false();要用map:size($m) = 0判空
替代方案:什么时候该用 XSLT 3.0 map/array?
它们适合做「结构化中间数据」,而非通用循环工具。真实场景中更常用:
- 把 XML 节点集转成 map 做快速查找(比如 ID → 元素映射)
- 用
array:for-each+array:filter处理分组后的一维结果(比嵌套xsl:for-each更紧凑) - 配合
xsl:iterate实现状态累积(例如计数、拼接字符串) - 避免频繁调用
key()或//—— 预建 map 查表更快
如果你只是想“对每个节点执行一个函数”,老老实实用 xsl:for-each 或 xsl:iterate 更稳;map/array 的价值在于表达「键值关系」和「有序集合语义」,不是语法糖。

