Reputation: 7736
I'm trying to XPath into some JSON using the same technique I would use to access XML. Below are 2 equivalent structures with the same XPath applied.
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"]
)
I would expect the same result for both but I get the following:
XML Result
<bas>findme</bas>
JSON result
{
"bas": "findme",
"boo": "324"
}
Why does this not produce the same result?
Upvotes: 2
Views: 501
Reputation: 20414
In MarkLogic the text property bas
is a named text node, something that doesn't exist in XML space. It is designed such that something like //bas
would work for both. Because of the named text node, the tree structure is different at deepest level:
element bas {
text { "findme" }
},
element boo {
text { "324" }
}
Versus:
object-node {
text bas { "findme" },
text boo { "324" }
}
Note: the latter is pseudo-code. Correct use of JSON constructors would be: object-node { "bas": "findme", "boo": "324" }
.
There might be a way to get closer to what you are after by making use of fn:name()
(fn:local-name()
doesn't work here, by the way). Try something like:
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!
Upvotes: 3