XML elements and JSON properties of the same name may be siblings. I.e.:
<container>
<value>value1</value>
<value>value2</value>
</container>
and
object-node {
"value" : "value1",
"value" : "value2"
}
are both valid, but I have not found a valid way to transform one into the other. It's invalid to dynamically build properties within an object-node
constructor, i.e.:
object-node {
for $v in $values
return 'value' : $v
}
Using maps doesn't work because the duplicate key names are collapsed:
xdmp:to-json(map:new((
map:entry("value", "value1"),
map:entry("value", "value2")))
)
=> {"value":"value2"}
And when using json:object
, the last key value is duplicated:
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"}
Joining maps using the +
operator is better, but it merges the duplicate keys into a single key with an array of values ({"value":["value1", "value2"]}
), which is still not what I want. Is there any way to build sibling JSON properties of the same name dynamically in XQuery?
Your JSON example:
object-node {
"value" : "value1",
"value" : "value2"
}
isn't really valid: or at any rate, it's best avoided. RFC 7159 says:
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.