JSON 的 xpath 与 XML 不同

xpath for JSON not the same as XML

我正在尝试使用与访问 XML 相同的技术将 XPath 转换为某些 JSON。下面是应用了相同 XPath 的 2 个等效结构。

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 space 中不存在。它的设计使得 //bas 之类的东西对两者都适用。由于命名的文本节点,树结构在最深层次上是不同的:

element bas {
  text { "findme" }
},
element boo {
  text { "324" }
}

对战:

object-node {
  text bas { "findme" },
  text boo { "324" }
}

注:后者为pseudo-code。 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!