我正在尝试使用与访问XML相同的技术将XPath转换为JSON。以下是两个应用了相同XPath的等效结构。
let $json := xdmp:unquote('{
"foo": {
"bar": {
"bas": "findme",
"boo": "324"
}
}
}')
let $xml := <xml>
<foo>
<bar>
<bas>findme</bas>
<boo>324</boo>
</bar>
</foo>
</xml>
return (
$xml//node()[./text() = "findme"],
$json//node()[./text() = "findme"]
)
我期望两者都得到相同的结果,但是得到以下结果:
XML结果
<bas>findme</bas>
JSON结果
{ "bas": "findme", "boo": "324"}
为什么这不会产生相同的结果?
最佳答案
在MarkLogic中,文本属性bas
是一个命名的文本节点,在XML空间中不存在。它的设计使//bas
之类的东西都适用。由于命名了文本节点,因此树的结构在最深层不同:
element bas {
text { "findme" }
},
element boo {
text { "324" }
}
与:
object-node {
text bas { "findme" },
text boo { "324" }
}
注意:后者是伪代码。正确使用JSON构造函数为:
object-node { "bas": "findme", "boo": "324" }
。可能有一种方法可以通过使用
fn:name()
来接近您所追求的(顺便说一下,fn:local-name()
在这里不起作用)。尝试类似的方法:let $json := xdmp:unquote('{
"foo": {
"bar": {
"bas": "findme",
"boo": "324"
}
}
}')
let $xml := <xml>
<foo>
<bar>
<bas>findme</bas>
<boo>324</boo>
</bar>
</foo>
</xml>
let $xml-text := $xml//text()[. = "findme"]
let $json-text := $json//text()[. = "findme"]
for $t in ($xml-text, $json-text)
return
if (name($t) eq "") then
$t/..
else
object-node { name($t): $t }
HTH!