如何在 MarkLogic 中将逗号放在生成 JSON 的正确位置?

How do I put commas in the right places generating JSON in MarkLogic?

如果花括号是最后一项,我会尽量避免在它后面加逗号。

  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 (',')
  )

不用检测最后一个元素并在循环中处理它,而是使用 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,']
  },
", ")   

在给定的情况下,您的输出是 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 代码中就会有额外的独立元素;更激进的攻击可能会逃脱结构并将全新的词典添加到您的外部列表中)。

我完全同意 Charles 的意见,我更喜欢 wst 的 string-join 比这更好,但为了完整起见,还有 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!