处理 XML 属性,使用 Marklogic 中的"custom"策略将 XML 转换为 JSON



尝试使用 Marklogic 9 上的自定义策略转换以下 XML,但我遇到了json:transform-to-json()函数如何处理属性值的问题。

输入 XML:

<values>
<option value="0">aaaa</option>
<option value="1">bbbb</option>
<option value="2">cccc</option>
</values>`

我想要的输出 JSON:

{
"values": {
"0": "aaaa",
"1": "bbbb",
"2": "cccc"
}
}

这是我的qcon代码:

xquery version "1.0-ml";
import module namespace json = "http://marklogic.com/xdmp/json"
at "/MarkLogic/json/json.xqy";

let $xml := <values>
<option value='0'>aaaa</option>
<option value='1'>bbbb</option>
<option value='2'>cccc</option>
</values>
(: OUTPUT WANTED: "values": {
"0": "aaaa",
"1": "bbbb",
"2": "cccc"
} :)
let $custom :=
let $config := json:config("custom")
return 
(map:put($config, "array-element-names", ("values", "option")),
map:put($config, "text-value", ("answer")),
$config)
return 
json:transform-to-json(
$xml, $custom
)

上面的脚本给了我一个不正确的输出:

{
"values": [
{
"option": [
{
"value": "0",
"answer": "aaa"
},
{
"value": "1",
"answer": "bbb"
},
{
"value": "2",
"answer": "ccc"
}
]
}
]
}

我的问题是仅使用 json:config 选项,是否可以构建我想要的输出?还是我需要在转换前或转换后进行一些解析?

我不相信仅使用json:config选项和json:transform-to-json()就可以实现您想要的。

您可以使用json:object()实现所需的输出:

let $xml := <values>
<option value='0'>aaaa</option>
<option value='1'>bbbb</option>
<option value='2'>cccc</option>
</values>
let $object := json:object() 
return 
( 
map:put($object, $xml/name(), map:new($xml/option/map:entry(@value, text()))), 
xdmp:to-json($object) 
)

请求的结果需要一定程度的预/后处理和/或繁琐的配置级别,恕我直言,最好避免。(您可以覆盖转换为 JSON 中使用的单个转换函数...但是你需要准确地知道它们是如何使用和实现的——可以通过阅读源代码获得(。

您正在一次请求多种转换。 1(结构转型,使复杂元素崩溃 2( 使用值作为元素名称 3( 使用无效的 XML QName 作为 JSON 字段名称。("0", "1" ...) 第一个可以通过首先将 XML 转换为在结构上等效于所需 json 的 XML 来完成......例如

<values>
<_0>aaaaa<_0>
<_1>bbbbbb<1>
....
</values>

然后将元素名称转换为 json("_0" -> "0" ...

后者可以通过使用未记录的配置值"json-name-from-element-qname"和/或"json-name-from-attribute-qname"来实现,将值设置为您自己的函数。

如果是我,我会使用 json:object 或文字 JSON 对象创建语法(对象 { .. } ("手动"编写转换以进行 JSON 创建。 这将比尝试诱骗转换为 json 做你想做的事情更简单、更高效。

最新更新