将 XML 个同名元素转换为 JSON 个同名属性

Transform XML elements of the same name into JSON properties of the same name

XML 元素和 JSON 同名属性可能是兄弟。即:

<container>
  <value>value1</value>
  <value>value2</value>
</container>

object-node {
  "value" : "value1",
  "value" : "value2"
}

都有效,但我还没有找到将一个转换为另一个的有效方法。在 object-node 构造函数中动态构建属性是无效的,即:

object-node {
  for $v in $values
  return 'value' : $v
}

使用映射不起作用,因为重复的键名被折叠:

xdmp:to-json(map:new((
  map:entry("value", "value1"), 
  map:entry("value", "value2")))
  )

=> {"value":"value2"}

并且当使用json:object时,最后一个键值重复:

json:object(<json:object>
  <json:entry key="value">
    <json:value>value1</json:value>
  </json:entry>
  <json:entry key="value">
    <json:value>value2</json:value>
  </json:entry>
</json:object>)

=> {"value":"value2", "value":"value2"}

使用 + 运算符连接映射更好,但它将重复的键合并为一个具有值数组 ({"value":["value1", "value2"]}) 的键,这仍然不是我想要的。有什么方法可以在 XQuery 中动态构建同名的同级 JSON 属性?

我认为不可能在 object-node() 构造函数中嵌入 FLWOR。

您可以构造一个字符串并使用 xdmp:eval() or xdmp:value():

求值
let $container := 
    <container>
      <value>value1</value>
      <value>value2</value>
    </container>

return
  xdmp:value(
   "object-node {" || 
     fn:string-join($container/value ! ('"' || local-name() || '": "' || . || '"'), ",") || 
   " }"
  )

或者构建 JSON 字符串并使用 xdmp:unquote():

let $container := 
    <container>
      <value>value1</value>
      <value>value2</value>
    </container>

return
  xdmp:unquote(
   "{" || 
     fn:string-join($container/value ! ('"' || local-name() ||'": "' || . || '"'), ",") || 
   "}"
  )

您的 JSON 示例:

object-node {
  "value" : "value1",
  "value" : "value2"
}

不是真的有效:或者无论如何,最好避免。 RFC 7159 说:

When the names within an object are not unique, the behavior of software that receives such an object is unpredictable. Many implementations report the last name/value pair only. Other implementations report an error or fail to parse the object, and some implementations report all of the name/value pairs, including duplicates.