我需要从地图
创建一个特定格式的文档我有以下代码:
declare function local:buid-map-doc(
$wijk as xs:string,
$wm as map:map) as element()
{
let $a := for $k in map:keys($wm)
let $v := map:get($wm,$k)
return element x {$v}
return <y>{$a}</y>
};
let $wijk := "101101"
let $wm := map:map()
let $p := map:put($wm, "cat1:::k1",45683)
let $p := map:put($wm, "cat1:::k2",123)
let $p := map:put($wm, "cat2:::k2",123)
return local:buid-map-doc($wijk,$wm)
给出:
<y>
<x>123</x>
<x>123</x>
<x>45683</x>
</y>
但我想拥有地图:键我的元素名称...... 如果我这样做:
declare function local:buid-map-doc(
$wijk as xs:string,
$wm as map:map) as element()
{
let $a := for $k in map:keys($wm)
let $v := map:get($wm,$k)
return element {$k} {$v}
return <y>{$a}</y>
};
let $wijk := "101101"
let $wm := map:map()
let $p := map:put($wm, "cat1:::k1",45683)
let $p := map:put($wm, "cat1:::k2",123)
let $p := map:put($wm, "cat2:::k2",123)
return local:buid-map-doc($wijk,$wm)
然后我得到错误:
[1.0-ml] XDMP-QNAMELEXFORM:让$ s:= fn:QName(&#34; http://www.example.com/example&#34;,&#34; k&#34;) - 无效的词汇表格的QName
增加:
理想情况下,我希望获得这样的输出,可能还有更深的嵌套:
<results>
<cat1>
<k1>45683</k1>
<k2>123</k2>
</cat1>
<cat2>
<k2>123</k2>
</cat2>
</results>
答案 0 :(得分:2)
对于computed element constructors,元素名称的表达式必须放在括号中:CompElemConstructor ::= "element" (QName | ("{" Expr "}")) "{" ContentExpr? "}"
declare function local:buid-map-doc(
$wijk as xs:string,
$wm as map:map) as element()
{
let $a :=
for $k in map:keys($wm)
let $v := map:get($wm, $k)
return element { replace($k, ':::', '-')} { $v }
return <y>{$a}</y>
};
答案 1 :(得分:1)
您的代码存在的问题是您的地图密钥不是有效的QName。因此,实际的错误ID是正确的,但它报告错误的代码确实很奇怪。我会确保在MarkLogic上报告。
解决方案非常简单,不要在map:keys中使用冒号,或者只使用一个冒号,并在匹配之前使用已知的命名空间前缀。例如。这会奏效:
declare function local:buid-map-doc(
$wijk as xs:string,
$wm as map:map) as element()
{
let $a := for $k in map:keys($wm)
let $v := map:get($wm,$k)
return element {$k} {$v}
return <y>{$a}</y>
};
let $wijk := "101101"
let $wm := map:map()
let $p := map:put($wm, "cat1_k1",45683)
let $p := map:put($wm, "cat1_k2",123)
let $p := map:put($wm, "cat2_k2",123)
return local:buid-map-doc($wijk,$wm)
增加:
如果三重冒号实际上表示层次结构,则最好先将展平的地图转换为嵌套地图。将嵌套映射转换为嵌套XML非常简单。这是构建嵌套映射的粗略实现:
declare function local:nest-keys($nested-map, $keys, $value) {
let $key := $keys[1]
let $remainder := $keys[position() > 1]
return
if ($key) then
let $_ :=
if (not(map:contains($nested-map, $key))) then
map:put($nested-map, $key, map:map())
else()
let $key-map :=
map:get($nested-map, $key)
return
if ($remainder) then
local:nest-keys($key-map, $remainder, $value)
else
map:put($nested-map, $key, $value)
else
()
};
let $map := map:map(
<map:map xmlns:map="http://marklogic.com/xdmp/map">
<map:entry>
<map:key>cat1:::var1:::seg1</map:key>
<map:value>waarde1</map:value>
</map:entry>
<map:entry>
<map:key>cat1:::var1:::seg2</map:key>
<map:value>waarde2</map:value>
</map:entry>
<map:entry>
<map:key>cat1:::var2:::seg1</map:key>
<map:value>waarde3</map:value>
</map:entry>
<map:entry>
<map:key>cat1:::var2:::seg2</map:key>
<map:value>waarde4</map:value>
</map:entry>
<map:entry>
<map:key>cat2:::var1:::seg1</map:key>
<map:value>waarde5</map:value>
</map:entry>
</map:map>
)
let $nested-map := map:map()
let $_ :=
for $key in map:keys($map)
let $keys := tokenize($key, ":::")
return
local:nest-keys($nested-map, $keys, map:get($map, $key))
return $nested-map
HTH!