XQuery中如何正确拼接序列结果以得到预期输出?
首先,咱们来拆解你遇到的问题:
你报错的核心原因是**concat()函数只能接受单个原子值(比如单个字符串或文本节点)作为参数**,但你的$desc和$ver其实是节点序列——因为//Desarrollador[@CodigoDes="D02"]下存在多个Programa元素,所以$b/Programa/Descripcion/text()会返回所有匹配的Descripcion文本节点组成的序列,$ver同理。直接把序列传给concat()就会触发"Item expected, sequence found"的错误。
接下来给你两种符合需求的解决方案:
方案1:遍历每个Programa元素(逻辑更清晰,推荐)
既然每个Programa对应一组Descripcion和Version,咱们直接遍历每个Programa,这样每次处理的都是单个文本节点,就能安全使用concat()了:
for $prog in //Desarrollador[@CodigoDes = "D02"]/Programa let $desc := $prog/Descripcion/text() let $ver := $prog/Version/text() return <salida>{concat($desc, " ", $ver)}</salida>
如果你的需求是把所有Programa的拼接结果合并成一个字符串,再放到<salida>里,可以用string-join把多个拼接后的字符串连起来:
let $all-programs := //Desarrollador[@CodigoDes = "D02"]/Programa let $combined-items := for $prog in $all-programs return concat($prog/Descripcion/text(), " ", $prog/Version/text()) return <salida>{string-join($combined-items, "")}</salida>
这个写法会先为每个Programa生成Descripcion + 空格 + Version的字符串,再把所有这些字符串拼接成最终结果,正好匹配你想要的Gesti贸n Discos 3 DurosImpresora 2格式。
方案2:处理序列中的对应项(保留外层遍历逻辑)
如果你坚持要保留外层遍历Desarrollador的写法,可以通过索引匹配对应的Descripcion和Version项(前提是每个Programa都有对应的描述和版本):
for $b in //Desarrollador[@CodigoDes = "D02"] let $desc-list := $b/Programa/Descripcion/text() let $ver-list := $b/Programa/Version/text() let $combined := for $i in 1 to count($desc-list) return concat($desc-list[$i], " ", $ver-list[$i]) return <salida>{string-join($combined, "")}</salida>
最终效果验证
用上述方案1的第二个写法,就能得到你预期的输出:
Gesti贸n Discos 3 DurosImpresora 2
内容的提问来源于stack exchange,提问作者Sergio Cavero

