我正在尝试使用与访问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!

10-04 18:27