构造JSON

构造JSON,json,marklogic,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) ret

我的文档是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

出现该错误是因为变量
$cat
不在嵌套的
元素的范围内。它在前面的范围中定义,因此不可用

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

{
  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>
  )
}
更新:提供的JSON结构无效;我已经自由地将category属性转换为一个对象。这些XQuery示例将输出JSON,如下所示:

{"Catname":{"Vartwo":["Seg2one","Seg2two"], "Varname":["Seg1","Seg2","Seg3","Seg4"]}}
此方法使用functional maps 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)
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)
下面是相同的代码,使用过程映射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)
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”]}
,这似乎不是很有用。添加了要查看的输出后,我将进行更新。

您会收到该错误,因为变量
$cat
不在嵌套的
元素的范围内。它在前面的范围中定义,因此不可用

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

{
  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>
  )
}
更新:提供的JSON结构无效;我已经自由地将category属性转换为一个对象。这些XQuery示例将输出JSON,如下所示:

{"Catname":{"Vartwo":["Seg2one","Seg2two"], "Varname":["Seg1","Seg2","Seg3","Seg4"]}}
此方法使用functional maps 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)
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)
下面是相同的代码,使用过程映射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)
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”]}
,这似乎不是很有用。一旦您添加了想要查看的输出,我将进行更新。

您在第二个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>
  )
}
{
对于具有不同值的$cat($doc//ns:category/@name)返回(
{$cat}
{for$doc中的$var//ns:category[@name=$cat]//ns:variable/@name返回{$var}}
)
}

您错过了第二个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>
  )
}
{
对于具有不同值的$cat($doc//ns:category/@name)返回(
{$cat}
{for$doc中的$var//ns:category[@name=$cat]//ns:variable/@name返回{$var}}
)
}

您可以添加您想要的JSON输出吗?您可以添加您想要的JSON输出吗?谢谢。我已经添加了想要的输出。谢谢。我已经添加了想要的输出。