2014-04-17 41 views
1

我需要從地圖創建specificly格式的文檔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毫升] XDMP-QNAMELEXFORM:讓$ S:= FN:QName的( 「http://www.example.com/example」, 「K」) - 無效詞法爲的QName

形式增加:

理想我想更深層次的嵌套得到輸出這樣的,可能還有:

<results> 
    <cat1> 
     <k1>45683</k1> 
     <k2>123</k2> 
    </cat1> 
    <cat2> 
     <k2>123</k2> 
    </cat2> 
</results> 

回答

1

您的代碼的問題在於您的映射鍵不是有效的QName。所以,實際的錯誤編號是正確的,但它報告錯誤的編碼確實很奇怪。我會確保它在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!

+0

實際上在真正的問題,我們有3層的關鍵和最終的解決方案是使用嵌套地圖來獲得我們需要的結構... thx爲您的幫助 –

+0

@HugoKoopmans:我將分享與代碼最相關的部分上市.. – grtjn

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> 
}; 
+0

不,測試並且不工作...仍然[1.0-ml] XDMP-QNAMELEXFORM:let $ v:= map:get($ wm,$ k) - QName的無效詞法形式...有趣的部分是,它抱怨元素之前的行,但光標指向元素 –

+0

@HugoKoopmans正如grtjn在他的答案中指出的那樣,冒號字符不是有效的NCName,因爲它保留用作名稱空間前綴之間的分隔符和本地名稱。有關spec規則,請參閱:http://www.w3.org/TR/REC-xml/#NT-Char。我更新了答案以從元素QNames中刪除冒號。 – wst