XML 到 JSON 转换 Xquery Marklogic 期间返回的不同元素文本值

问题描述 投票:0回答:1

我们正在使用下面的示例 xml,并要求将其作为 JSON 响应返回。

所以我使用

json:transform-to-json()
函数来进行 XML 到 JSON 的转换。

在下面的示例中,当存在多个子

<title>
元素时,
<target>
的值不会按预期在 JSON 响应中返回。

例如

  1. 具有多个目标子元素的标题元素
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"
}
}
}
  1. 具有单个目标子元素的标题元素
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 xquery marklogic marklogic-10
1个回答
0
投票

我将分别解决以下每个问题:

首先,了解一些有关转换功能的主要概念非常重要,如转换哲学

中所述
  • 使用默认转换参数可以轻松快速地执行简单转换。
  • 使得执行语义无损转换成为可能。

还有更多,但这两个有助于了解结果的背景。

当我测试时,我从无损开始,并确保它仍然可以通过两种方式工作:

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()
    

© www.soinside.com 2019 - 2024. All rights reserved.