Marklogic如何从地图创建文档

时间:2014-04-17 15:01:44

标签: marklogic

我需要从地图

创建一个特定格式的文档

我有以下代码:

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>

2 个答案:

答案 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!