我的文档是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" ... }
答案 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)
这种方法的关键点是
此代码从您的示例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>
)
}