构造JSON

时间:2014-05-30 08:54:37

标签: json marklogic

我的文档是XML格式,我需要根据这个文档构建一个JSON格式。首先,我创建了一个返回正确XML结构的查询,但是当我将此查询转换为返回JSON时,我遇到了For Return问题。

Error: [1.0-ml] XDMP-UNDVAR: (err:XPST0008) Undefined variable $cat

原始查询:

let $tree :=
<tree>{for $cat in distinct-values($doc//ns:category/@name)
    return <cat name="{$cat}">
    { for $var in $doc//ns:category[@name = $cat]//ns:variable/@name
      return <var name="{$var}"> 
      }  
      </var>
    }
    </cat>

  }
</tree>

return $tree

数据:

<category name="Catname">
  <variable name="Varname">
    <segment name="Seg1">9</segment>
    <segment name="Seg2">33</segment>
    <segment name="Seg3">32</segment>
    <segment name="Seg4">22</segment>
  </variable>
  <variable name="Vartwo">
    <segment name="Seg2one">1</segment>
    <segment name="Seg2two">2</segment>
  </variable>
</category>
<category> ....

新查询:

let $tree := 
json:array(
<json:array xmlns:json="http://marklogic.com/xdmp/json"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<json:value xsi:type="xs:string">
  {for $cat in distinct-values($doc//ns:category/@name) return $cat}
</json:value>
  <json:array>
    {for $var in $doc//ns:category[@name = $cat]//ns:variable/@name return $var}
  </json:array>
</json:array>          
)

return $tree

预期输出

{"Catname": ["Varname": ["Seg1", "Seg2", "Seg3"], "Vartwo": ["Seg2one", "Seg2two"]]},
{"Cat2" ... }

2 个答案:

答案 0 :(得分:2)

您收到该错误是因为变量$cat不在嵌套<json:array/>元素的范围内。它在前一个范围中定义,因此不可用。

我不确定您要创建什么JSON结构,但使用该XML序列化来创建JSON肯定很尴尬。我更喜欢这样的方法:

更新:提供的JSON结构无效;我已经冒昧地将类别属性转换为对象。这些XQuery示例将输出JSON,如下所示:

{"Catname":{"Vartwo":["Seg2one","Seg2two"], "Varname":["Seg1","Seg2","Seg3","Seg4"]}}

此方法使用功能映射API:

let $map :=
  map:new(
    for $cat in distinct-values($doc//ns:category/@name)
    return
      map:entry($cat,
        for $var in $doc//ns:category[@name = $cat]//ns:variable
        let $name := $var/@name/fn:string()
        return map:entry($name, json:to-array($var/ns:segment/@name/fn:string())) ))
return xdmp:to-json($map)

使用程序贴图API,这里的代码相同:

let $map := map:map()
let $_ :=
  for $cat in distinct-values($doc//ns:category/@name)
  let $cat-map := map:map()
  let $_ :=
    for $var in $doc//ns:category[@name = $cat]//ns:variable
    let $name := $var/@name/fn:string()
    return map:put($cat-map, $name, json:to-array($var/ns:segment/@name/fn:string()))
  return map:put($map, $cat, $cat-map)
return xdmp:to-json($map)

这种方法的关键点是

  • 使用json:to-array()
  • 从XQuery序列构造数组
  • 使用xdmp:to-json()
  • 从地图构造对象

此代码从您的示例XML返回以下JSON:{"Catname":["Varname"]},这看起来并不是非常有用。一旦您添加了想要查看的输出,我就会更新。

答案 1 :(得分:2)

你错过了第二个for循环中的上下文

你可能想做这样的事情:

{
  for  $cat in distinct-values($doc//ns:category/@name) return (
    <json:value xsi:type="xs:string">
      {$cat}
    </json:value>
    <json:array>
      {for $var in $doc//ns:category[@name = $cat]//ns:variable/@name return <json:value>{$var}</json:value>}
    </json:array>
  )
}