【问题标题】:Constructing JSON构造 JSON
【发布时间】:2014-05-30 08:54:36
【问题描述】:

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

【问题讨论】:

  • 您可以添加您想要的 JSON 输出吗?

标签: json marklogic


【解决方案1】:

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

我不确定您要创建什么 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"]},这似乎不是很有用。一旦你添加了你想看到的输出,我会更新。

【讨论】:

  • 谢谢。我已经添加了想要的输出。
【解决方案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>
  )
}

【讨论】:

    猜你喜欢
    • 2013-08-20
    • 2018-12-03
    • 2019-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-21
    • 2018-06-24
    相关资源
    最近更新 更多