2017-03-15 31 views
1

如果是最後一項,我試圖在花括號後面沒有逗號。如何在MarkLogic的正確位置生成JSON?

for $row in /md:row 
    let $test := $row/md:test/text() 
    let $last := $row/*[fn:position() = fn:last()] 

    return (
    '{ 
    "test": { 
    "type": "test", 
    "test": [',$testa,',',$testb,'] 
    }  
    }', 
    if($last) 
    then '' 
    else (',') 
) 

回答

6

在給定的情況下,你的輸出是JSON,使用MarkLogic爲此目的提供的電話號碼爲json:transform-to-json

import module namespace json = "http://marklogic.com/xdmp/json" 
    at "/MarkLogic/json/json.xqy"; 

json:transform-to-json(
    <json type="array" xmlns="http://marklogic.com/xdmp/json/basic">{ 
    for $row in /md:row 
    let $test := $row/md:test/text() 
    return (
     <json type="object"> 
     <test type="object"> 
      <type type="string">test</type> 
      <test type="array"> 
      <item type="string">{$test}</item> <!-- testa and testb were undefined --> 
      <item type="string">{$test}</item> 
      </test> 
     </test> 
     </json> 
    ) 
    }</json> 
) 

在這些問題中,這避免:

  • 你並不需要在所有添加語法逗號- 他們完全被transform-to-json調用生成,模擬法庭是整個問題的集合。
  • 無意中格式錯誤的輸出(如果您的XML文本節點包含需要在JSON中轉義爲有效的字符 - 例如換行符)。
  • 注入攻擊(如果您的$testa$testb包含test", "hello", "world", "foo,那麼您的JSON代碼中會包含額外的單獨元素;更積極的攻擊可能會導致結構轉移並將新的字典添加到外部列表中)。
+0

感謝您通知有關問題。 – Jon

2

代替檢測的最後一個元素,你的循環中處理這種情況,使用string-join,自動完成你想要的東西:

string-join(
    for $row in /md:row 
    let $test := $row/md:test/text() 
    let $last := $row/*[fn:position() = fn:last()] 
    return (
    '{ 
    "test": { 
    "type": "test", 
    "test": [',$testa,',',$testb,'] 
    }, 
", ") 
+1

夠公平的,但我會打電話給這個(通過字符串連接生成JSON)*非常不好的做法(容易發生注入攻擊,格式錯誤的輸出等)。正如我們對通過連接字符串來生成XML的人不滿意的一樣,以這種方式生成JSON也有類似的缺陷。另請參閱https://docs.marklogic.com/json:transform-to-json。 –

+1

@CharlesDuffy我沒有注意到MarkLogic標籤!我很清楚,這不是建議,我保證我不會在家裏做:) – wst

+0

由於不好的做法,我更新了答案。謝謝! – Jon

0

我完全與查爾斯的意見一致,我喜歡的WST字符串加入比這更好的,但爲了完整起見,這裏也是at聲明是FLWOR表達式的一部分。你可以用這樣的東西:

let $rows := (1 to 10) 
    let $last := fn:count($rows) 
    for $row at $index in $rows 
    let $test := string($row) 

    return (
    '{ 
    "test": { 
    "type": "test", 
    "test": [',$test,'] 
    }  
    }', 
    if($index eq $last) 
    then '' 
    else (',') 
) 

HTH!