XSLT 3.0中未知JSON节点为map/array时的遍历取值方法
XSLT 3.0 处理混合map/array类型JSON的方案
直接针对你提出的两个问题给出标准实现方案:
1. 类型判断方法
你之前使用castable无效是因为该语法仅用于判断原子类型的可转换性,判断JSON对应的map/array函数项类型,直接使用XPath 3.1标准的instance of类型判断即可,不存在兼容问题:
- 判断目标为map类型:
?book instance of map(*),返回布尔值true/false - 判断目标为array类型:
?book instance of array(*),返回布尔值true/false
两种语法无法直接通用的核心原因是:lookup操作符?*作用在array上时会返回数组所有成员的序列,但作用在map上时会返回map所有字段值的序列,直接对map使用?book?*?name会因为拿到的是id、name的原子值序列而抛出错误。
2. 兼容两种类型的统一取值语法
不需要分支判断、也不需要try/catch捕获错误,有两种可靠实现:
最优通用写法
直接使用XPath 3.1内置的map:find函数,天然兼容任意嵌套的map/array结构,写法为:
map:find(?book, 'name')?*
该函数会自动遍历输入的?book结构,无论它是单个map、还是单层/多层array包裹的map,都会检索所有键名为name的字段值,最终返回所有匹配值的序列,不会因为类型不匹配抛出错误,鲁棒性最高。
明确分支写法
如果你不需要深层匹配、要严格控制取值逻辑,可以结合前面的类型判断写分支逻辑,完全替代try/catch:
if (?book instance of map(*)) then ?book?name else ?book?*?name
这种写法只会根据book的顶层类型选择对应取值语法,不会吞掉其他运行时错误(比如字段不存在、值类型不符合预期等),比try/catch更易调试。
方案说明
你当前使用的xsl:try/catch变通方案存在明显缺陷:它会捕获所有取值相关的运行时错误,不仅是类型不匹配的错误,比如字段缺失、值类型异常等问题都会被误判为array类型走分支逻辑,会掩盖真实的数据结构问题,提高排查成本,不建议在生产环境使用。
内容的提问来源于stack exchange,提问作者shakobe
相关产品推荐
相关产品推荐

