Marklogic json:config 生成“_children”
Marklogic json:config generate "_children"
我不明白为什么 Marklogic json:config 生成“_children”。我怎样才能排除“_children”。我看到所有枚举的 children 都返回 parents,但是 JSON 输出中有很多额外的垃圾。
let $config := json:config("custom")
let $_ := map:put( $config, "full-element-names",xs:QName("Nav:keynavlist")
Json 输出:
"Navigators": {
"keynavlist": {
"_children": [
{
"keynav": {
"_value": "Fuel Cells"
}
},
{
"keynav": {
"_value": "Microorganisms"
}
},
{
"keynav": {
"_value": "Waste Treatment"
}
我猜你想要这样的东西:
{
"Navigators": {
"keynavlist": [{
"keynav": "Fuel Cells"
}, {
"keynav": "Microorganisms"
}, {
"keynav": "Waste Treatment"
}]
}
}
但最接近 json 转换库的是:
{
"Navigators": {
"keynavlist": {
"keynav": ["Fuel Cells", "Microorganisms", "Waste Treatment"]
}
}
}
使用:
xquery version "1.0-ml";
import module namespace json="http://marklogic.com/xdmp/json" at "/MarkLogic/json/json.xqy";
let $config := json:config("custom")
let $_ := map:put($config, "array-element-names", ("keynav"))
return json:transform-to-json(
<Navigators>
<keynavlist>
<keynav>Fuel Cells</keynav>
<keynav>Microorganisms</keynav>
<keynav>Waste Treatment</keynav>
</keynavlist>
</Navigators>,
$config
)
考虑使用递归函数构建 json,可能是这样的:
declare function local:xml-to-json($nodes) {
for $node in $nodes
return typeswitch ($node)
case element() return
if ($node/attribute() or ($node/element() and $node/text())) then
object-node {
local-name($node): object-node {
"@": array-node{ local:xml-to-json($node/attribute()) },
"_": array-node { local:xml-to-json($node/node()) }
}
}
else
object-node {
local-name($node): array-node{ local:xml-to-json($node/node()) }
}
case attribute() return
object-node {
local-name($node): data($node)
}
default return $node
};
local:xml-to-json(
<Navigators>
<keynavlist>
<keynav>Fuel Cells</keynav>
<keynav>Microorganisms</keynav>
<keynav>Waste Treatment</keynav>
</keynavlist>
</Navigators>
)
HTH!
回答你的第一个问题
"I don't understand why Marklogic json:config generates "_children"
'custom' 配置旨在尽可能合理地支持 双向 JSON <> XML 转换。需要您引用的 "extra junk"(例如 _children)以反转过程并生成原始 XML。
'basic' 策略用于从 JSON 到 XML 的简单单向转换,而完整策略用于反向转换(xml 到 JSON)—— 同时保留尽可能多的信息。
由于您要从 XML 翻译成 JSON,其中任何 xml 元素都可能同时具有属性和子元素,并且子元素可能具有重名,因此它们不能转换为简单的 JSON 对象而不会丢失数据(在一般情况下)。
'custom' 策略具有很大的灵活性(又名 'complexity')来解决 'My Case' 很少 'The General Case' 或 "Your Case" 这一事实。
一个这样的配置选项是能够指定 xml qnames 应该转换为数组而不是“_children”
"array-element-names"
查看本页的最后一个示例:https://docs.marklogic.com/json:config
xquery version "1.0-ml";
import module namespace json = "http://marklogic.com/xdmp/json"
at "/MarkLogic/json/json.xqy";
declare variable $doc := <a><b attr="d">c</b></a>;
let $c := json:config("custom") ,
$_ := map:put( $c, "array-element-names", (xs:QName("a"),xs:QName("b")) ),
$_ := map:put( $c, "attribute-names", ("attr" ) ),
$_ := map:put( $c, "text-value", "LABEL" ),
$j := json:transform-to-json($doc ,$c ),
$x := json:transform-from-json($j,$c)
return ($j, $x)
(: The JSON property name "LABEL" is used to hold the text value from
the element <b/>. Without the "text-value" option, the property name
would be "_value". The query produces the following output:
{"a":[{"b":[{"attr":"d", "LABEL":"c"}]}]}
<a><b attr="d">c</b></a> :)
在某些时候——实现具体个案转换所需的 'configuration' 数量变得更复杂,作为策略配置来做,而作为本地 xquery 代码来做则不那么复杂,如 grtjn 所示,当如何'tweek' 为给定用例自定义配置变得过于乏味或不明显时,这是推荐的解决方案。
我发现 json:transform 和 post 预处理的组合最适合我。 YMMV
我不明白为什么 Marklogic json:config 生成“_children”。我怎样才能排除“_children”。我看到所有枚举的 children 都返回 parents,但是 JSON 输出中有很多额外的垃圾。
let $config := json:config("custom")
let $_ := map:put( $config, "full-element-names",xs:QName("Nav:keynavlist")
Json 输出:
"Navigators": {
"keynavlist": {
"_children": [
{
"keynav": {
"_value": "Fuel Cells"
}
},
{
"keynav": {
"_value": "Microorganisms"
}
},
{
"keynav": {
"_value": "Waste Treatment"
}
我猜你想要这样的东西:
{
"Navigators": {
"keynavlist": [{
"keynav": "Fuel Cells"
}, {
"keynav": "Microorganisms"
}, {
"keynav": "Waste Treatment"
}]
}
}
但最接近 json 转换库的是:
{
"Navigators": {
"keynavlist": {
"keynav": ["Fuel Cells", "Microorganisms", "Waste Treatment"]
}
}
}
使用:
xquery version "1.0-ml";
import module namespace json="http://marklogic.com/xdmp/json" at "/MarkLogic/json/json.xqy";
let $config := json:config("custom")
let $_ := map:put($config, "array-element-names", ("keynav"))
return json:transform-to-json(
<Navigators>
<keynavlist>
<keynav>Fuel Cells</keynav>
<keynav>Microorganisms</keynav>
<keynav>Waste Treatment</keynav>
</keynavlist>
</Navigators>,
$config
)
考虑使用递归函数构建 json,可能是这样的:
declare function local:xml-to-json($nodes) {
for $node in $nodes
return typeswitch ($node)
case element() return
if ($node/attribute() or ($node/element() and $node/text())) then
object-node {
local-name($node): object-node {
"@": array-node{ local:xml-to-json($node/attribute()) },
"_": array-node { local:xml-to-json($node/node()) }
}
}
else
object-node {
local-name($node): array-node{ local:xml-to-json($node/node()) }
}
case attribute() return
object-node {
local-name($node): data($node)
}
default return $node
};
local:xml-to-json(
<Navigators>
<keynavlist>
<keynav>Fuel Cells</keynav>
<keynav>Microorganisms</keynav>
<keynav>Waste Treatment</keynav>
</keynavlist>
</Navigators>
)
HTH!
回答你的第一个问题
"I don't understand why Marklogic json:config generates "_children"
'custom' 配置旨在尽可能合理地支持 双向 JSON <> XML 转换。需要您引用的 "extra junk"(例如 _children)以反转过程并生成原始 XML。 'basic' 策略用于从 JSON 到 XML 的简单单向转换,而完整策略用于反向转换(xml 到 JSON)—— 同时保留尽可能多的信息。
由于您要从 XML 翻译成 JSON,其中任何 xml 元素都可能同时具有属性和子元素,并且子元素可能具有重名,因此它们不能转换为简单的 JSON 对象而不会丢失数据(在一般情况下)。
'custom' 策略具有很大的灵活性(又名 'complexity')来解决 'My Case' 很少 'The General Case' 或 "Your Case" 这一事实。
一个这样的配置选项是能够指定 xml qnames 应该转换为数组而不是“_children” "array-element-names"
查看本页的最后一个示例:https://docs.marklogic.com/json:config
xquery version "1.0-ml";
import module namespace json = "http://marklogic.com/xdmp/json"
at "/MarkLogic/json/json.xqy";
declare variable $doc := <a><b attr="d">c</b></a>;
let $c := json:config("custom") ,
$_ := map:put( $c, "array-element-names", (xs:QName("a"),xs:QName("b")) ),
$_ := map:put( $c, "attribute-names", ("attr" ) ),
$_ := map:put( $c, "text-value", "LABEL" ),
$j := json:transform-to-json($doc ,$c ),
$x := json:transform-from-json($j,$c)
return ($j, $x)
(: The JSON property name "LABEL" is used to hold the text value from
the element <b/>. Without the "text-value" option, the property name
would be "_value". The query produces the following output:
{"a":[{"b":[{"attr":"d", "LABEL":"c"}]}]}
<a><b attr="d">c</b></a> :)
在某些时候——实现具体个案转换所需的 'configuration' 数量变得更复杂,作为策略配置来做,而作为本地 xquery 代码来做则不那么复杂,如 grtjn 所示,当如何'tweek' 为给定用例自定义配置变得过于乏味或不明显时,这是推荐的解决方案。
我发现 json:transform 和 post 预处理的组合最适合我。 YMMV