如何高效运用XSLT 3.0的map和array功能?

2026-04-29 13:224阅读0评论SEO教程
  • 内容介绍
  • 相关推荐

本文共计839个文字,预计阅读时间需要4分钟。

如何高效运用XSLT 3.0的map和array功能?

直接说结论:

真正可用的是:

  • 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>

常见报错和坑点

以下错误几乎都源于类型或命名空间缺失:

  • XPST0003XPDY0002:未声明 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-eachxsl:iterate 更稳;map/array 的价值在于表达「键值关系」和「有序集合语义」,不是语法糖。

本文共计839个文字,预计阅读时间需要4分钟。

如何高效运用XSLT 3.0的map和array功能?

直接说结论:

真正可用的是:

  • 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>

常见报错和坑点

以下错误几乎都源于类型或命名空间缺失:

  • XPST0003XPDY0002:未声明 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-eachxsl:iterate 更稳;map/array 的价值在于表达「键值关系」和「有序集合语义」,不是语法糖。