XQuery中Map转指定结构序列数组的实现问询
解决XQuery中Map转特定格式数组的问题
我懂你这种纠结——要构建给fn:apply用的精准数组结构,既要让第一个序列里的'b'数量和b-key的元素数完全对应,又不能搞出嵌套过多或者过度扁平化的问题。咱们直接上可行的方案,再拆解细节:
核心实现代码
let $input := map { 'a-key': 'a-value', 'b-key': ['b-value-1', 'b-value-2'] } let $first-sequence := ( -- 处理a-key:存在就加入'a',否则为空序列 if (exists($input?a-key)) then 'a' else (), -- 遍历b-key的每个元素,每个元素对应一个'b' for $item in $input?b-key return 'b' ) let $values := ( -- 收集a-key的值(存在则加入) $input?a-key, -- 展开b-key的所有值(自动处理数组转序列) $input?b-key ) -- 构造目标数组:第一个元素是$first-sequence,后面跟着所有values元素 return array { ($first-sequence, $values) }
关键逻辑拆解
第一个序列的生成:
- 用条件判断处理
a-key的存在性,确保只有当a-key存在时,序列里才会有'a' - 用
for循环遍历b-key的每一个元素,每遍历一个就生成一个'b',完美匹配b-key的长度;如果b-key不存在或者是空数组,这部分就会生成空序列
- 用条件判断处理
值部分的收集:
$input?a-key会直接返回对应的值(不存在则为空序列)$input?b-key是数组,在序列上下文里会自动展开成单个元素的序列,刚好符合我们需要逐个加入数组的需求
数组构造:
- 用
array { ... }构造数组时,把$first-sequence作为第一个元素,然后用,拼接$values序列,这样$values里的每个元素都会成为数组的独立元素,不会嵌套
- 用
边界情况测试
- 当
a-key不存在时:
输入$input := map { 'b-key': ['x', 'y'] },输出为[ ('b', 'b'), 'x', 'y' ] - 当
b-key不存在时:
输入$input := map { 'a-key': 'test' },输出为[ ('a'), 'test' ] - 当
b-key是空数组时:
输入$input := map { 'a-key': 'test', 'b-key': [] },输出为[ ('a'), 'test' ] - 当两个key都不存在时:
输入$input := map { },输出为[ (), () ](如果需要优化这种情况,可以在最后加个过滤空序列的逻辑,比如array { filter(($first-sequence, $values), fn:exists) })
内容的提问来源于stack exchange,提问作者user2672537
相关产品推荐
相关产品推荐

