我们正在使用下面的示例 xml,并要求将其作为 JSON 响应返回。
所以我使用
json:transform-to-json()
函数来进行 XML 到 JSON 的转换。
在下面的示例中,当存在多个子
<title>
元素时,<target>
的值不会按预期在 JSON 响应中返回。
例如
xquery version "1.0-ml";
import module namespace json = "http://marklogic.com/xdmp/json"at "/MarkLogic/json/json.xqy";
let $a := <title-group><title><target id="1">224</target><target id="2">225</target>Part II</title></title-group>
let $config := json:config("custom")
let $_ := map:put( $config, "array-element-names","target")
let $put := map:put($config,"whitespace","ignore")
return json:transform-to-json($a,$config)
Output :
{
"title-group": {
"title": {
"target": [
{
"id": "1",
"_value": "224"
},
{
"id": "2",
"_value": "225"
}
],
"_value": "224225Part II"
}
}
}
xquery version "1.0-ml";
import module namespace json = "http://marklogic.com/xdmp/json"at "/MarkLogic/json/json.xqy";
let $a := <title-group><title><target id="1">224</target>Part II</title></title-group>
let $config := json:config("custom")
let $put := map:put($config,"whitespace","ignore")
return json:transform-to-json($a,$config)
Output :
{
"title-group": {
"title": {
"target": {
"id": "1",
"_value": "224"
},
"_value": "Part II"
}
}
}
当
_value
是数组/对象时,title
对象的 target
有所不同。我想了解这两种情况是如何工作的以及以下问题
1.需要做什么来纠正示例1中的标题值?
2.如果 XML 的格式如下,则 newspace 字符将添加到 json 响应 _value 中。如何处理这种情况?
XML:
<title-group>
<title>
<target id="1">224</target>
Part II
</title>
</title-group>
JSON Output :
{
"title-group": {
"title": {
"target": {
"id": "1",
"_value": "224"
},
"_value": "\nPart II\n"
}
}
}
我将分别解决以下每个问题:
首先,了解一些有关转换功能的主要概念非常重要,如转换哲学
中所述还有更多,但这两个有助于了解结果的背景。
当我测试时,我从无损开始,并确保它仍然可以通过两种方式工作:
json:transform-from-json(json:transform-to-json($xml,$config), $config)
。然后我开始了解 MarkLogic 通过单向转换做了什么。
<title-group>
<title>
<target id="1">224</target>
<target id="2">225</target>
Part II
</title>
</title-group>
关键是哲学的“基本”转换。在某些情况下,即使使用自定义,仅通过配置也无法实现所需的转换。
您的内容并不简单和基本 - 它包括文本和元素节点的组合(混合内容)。混合内容根本无法很好地转换为 JSON。这有点像要求这个:
{ [{some object} {some object}] "string"}
。
想象一下:
The <b>quick</b> brown fox jumped over the <b>lazy</b> dog
所以我可以用
quick
, lazy
定义一个数组 - 但是原始短语 The brown fox jumps over the dog
会发生什么?这就是我想要的吗?可能不会。任何不“简单”的东西在转换中都可能是不可预测的。
最后,完成
array-element
的提取,然后完成完整值(可能是 fn:data() 的连接)以捕获完整值。
我同意它在此示例中适用于单个目标:
<title-group>
<title>
<target id="2">225</target>
Part II
</title>
</title-group>
但是,有人可能会说,标题的价值仍然是 225 第2部分
要考虑的解决方案:
我经常需要修改 XML 以使转换更接近我想要的。这当然有助于混合内容节点的翻译。我通常使用简单的 XSLT 转换作为 JSON 的预处理步骤和 JSON 的后处理步骤来完成此任务。
一些例子: 将目标包装在目标元素中:
<title-group>
<title>
<targets>
<target id="1">224</target>
<target id="2">225</target>
</targets>
Part II
</title>
</title-group>
结果给出了一个可能可以接受的 JSON 结果(尽管有些人会对结构的“额外层”感到不舒服。此外,根据我的感觉,混合内容节点不能转换为 JSON,我觉得它有点丑陋正如狐狸样本中所阐述的那样。
将值包装在值元素中:
<title-group>
<title>
<target id="1">224</target>
<target id="2">225</target>
<value>Part II</value>
</title>
</title-group>
我的首选解决方案是将目标元素实际包装在目标元素中:
<title-group>
<title>
<targets>
<target id="1">224</target>
<target id="2">225</target>
</targets>
<value>Part II</value>
</title>
</title-group>
加线返程
"_value": "\nPart II\n"
这是预期的输出。请记住,这些值是无损的(请参阅原始参考文献)。这里的混乱可能与配置有关
whitespace=ignore
。确实,\n
是空白 - 即使在 XMl 中也是如此。但是,whitespace=ignore
作为配置的一部分
来自自定义策略属性: 在转换为 JSON 时,如何处理“仅”包含空格的 XML 文本值。允许值:“保留”、“忽略”。默认值:“保留”。 这本质上是关于如何处理空值,而不是在内容内部做什么。
您必须在之前(
fn:normalize-space()
或之后)自己清理数据(例如在js中使用
Prototyp.trim()
)