示例XQuery(使用Saxon-HE,版本9.8.0.6)
xquery version "3.1";
let $xml := <simple>
<hello>Hello World!</hello>
</simple>
return fn:serialize(map{
'greeting': data($xml/hello),
'number': data($xml/number) (: ? how to add this entry only if there is a number ? :)
}, map{'method':'json', 'indent':true()})
输出:
{
"number":null,
"greeting":"Hello World!"
}
问题
如何阻止null
值的条目(在本例中为“数字”)?或者更具体地说,在这种情况下:如果只是一个数字,如何添加“数字”条目?
注意:我了解map:entry
和map:merge
。我正在寻找没有这些函数的解决方案,所以“内联”(在地图构造函数中)。
更新
根据@joewiz的答案,这是不可能的。这是我们最接近的:
xquery version "3.1";
declare namespace map="http://www.w3.org/2005/xpath-functions/map";
let $xml := <simple>
<hello>Hello World!</hello>
</simple>
return fn:serialize(
map:merge((
map:entry('greeting', data($xml/hello)),
let $n := number($xml/number) return if ($n) then map:entry('number', $n) else()
)),
map{'method':'json', 'indent':true()})
答案 0 :(得分:3)
如果你经常做这件事,那么你可以做到这一点:
declare function f:addConditionally($map, $key, $data) as map(*) {
if (exists($data)) then map:put($map, $key, $data) else $map
};
let $m :=
map{}
=> f:addConditionally('greeting', data($xml/hello))
=> f:addConditionally('number', data($xml/number))
答案 1 :(得分:1)
根据Map Constructors上的XQuery 3.1规范,映射构造函数由映射构造函数条目组成,映射构造函数条目本身由映射键表达式和映射值表达式组成。换句话说,映射构造函数条目不是通用表达式,不能容纳条件表达式,例如:
map { if ($condition) then "key": "value" else () }
如果除了键值表达式对之外还需要在地图中放置任何内容,则需要放弃地图构造函数并返回map:merge()
和map:entry()
。上述情况的正确语法如下:
map:merge( if ($condition) then map:entry("key", "value") else () )