如何从 marklogic 中的 xml 文档中获取 json 结果
how to get json results from xml document in marklogic
我正在尝试使用 2 层服务器端 javascript 应用程序 return JSON 格式的 XML 文档。我知道 MarkLogic 可以使用 REST api 在 JSON 和 XML 格式之间轻松切换。
然而,下面returnsxml:
cts.search('something', ['format-xml']) // options may be omitted
但这return没什么:
cts.search('something', ['format-json'])
根据文档,我认为我已经正确使用了该功能。
这是否可以使用服务器端 javascript?
更新:
使用transformToJsonObject
如下:
var json = require('/MarkLogic/json/json.xqy');
var doc = fn.doc('/content/rss/72eb9bf835521446be8d2176e1ac9d22.xml')
var jsonDoc = json.transformToJsonObject(doc, json.config('custom'));
jsonDoc
我收到以下错误:
500 Internal Server Error
XDMP-Whosebug: Stack overflow
in /MarkLogic/json/custom.xqy, at 493:23,
in json-custom:is-ignore-attribute#2(json:object(<json:object xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:json="http://marklogic.com/xdmp/json"><json:entry key="element-qname-from-json-name"><json:value xsi:t...</json:object>...XDMP-ATOMIZEFUNC: (err:FOTY0013) Functions cannot be atomized...), fn:doc("/content/rss/72eb9bf835521446be8d2176e1ac9d22.xml")/newsitem/article/*:html/*:head/*:script[5]/*:script/*:script/*:script/*:link/*:script/*:script/*:script/*:script/*:script/*:script/*:style/*:script/*:script/*:script/*:script/*:script/*:script/*:script/*:script/*:script/*:script/*:link/*:script/*:script/*:noscript/*:link/*:meta/*:body/*:div/*:div/*:div/*:script/*:div/*:div/*:script/*:script/*:div/*:div/*:script/*:script/*:script/*:script/*:noscript/*:p/*:header/*:div/*:div/*:div/*:a/*:section/*:div/*:h2/*:ul/*:li/*:a/*:li/*:a/*:div/*:div/*:a/*:img/*:span/*:script/*:nav/*:div/*:h2/*:ul/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:span/*:div/*:a/*:form/*:div/*:label/*:div/*:script/*:div/*:div/*:div/*:div/*:div/*:a/*:svg/*:title/*:h2/*:a/*:div/*:button/*:div/*:ul/*:li/*:a/*:span/*:li/*:a/*:span/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:div/*:nav/*:a/*:span/*:span/*:ul/*:li/*:a/*:span/*:li/*:a/*:span/*:span/*:div/*:div/*:script/*:script/*:div/*:div/*:span/*:span/*:a/*:div/*:div/*:script/*:script/*:div/*:div/*:div/*:span/*:span/*:a/*:div/*:div/*:script/*:script/*:div/*:div/*:div/*:div/*:h1/*:div/*:ul/*:li/*:div/*:li/*:span/*:a/*:div/*:figure/*:span/*:img/*:span/*:span/*:figcaption/*:span/*:span/*:p/*:p/*:p/*:p/*:p/*:div/*:div/*:script/*:script/*:h2/*:p/*:p/*:figure/*:span/*:div/*:span/*:span/*:figcaption/*:span/*:span/*:p/*:p/*:p/*:p/*:p/*:p/*:p/*:p/*:div/*:a/*:h2/*:a/*:ul/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:div/*:div/*:div/*:h2/*:div/*:ul/*:li/*:a/*:div/*:div/*:div/*:span/*:div/*:div/*:li/*:a/*:div/*:div/*:div/*:span/*:div/*:div/*:li/*:a/*:div/*:div/*:div/*:span/*:div/*:div/*:li/*:a/*:div/*:div/*:div/*:span/*:div/*:div/*:li/*:a/*:div/*:div/*:div/*:span/*:div/*:div/*:li/*:a/*:div/*:div/*:div/*:span/*:div/*:div/*:li/*:a/*:div/*:div/*:div/*:span/*:div/*:div/*:li/*:a/*:div/*:div/*:div/*:span/*:div/*:div/*:li/*:a/*:div/*:div/*:div/*:span/*:div/*:div/*:div/*:div/*:div/*:h2/*:div/*:ul/*:li/*:div/*:div/*:a/*:div/*:span/*:p/*:div/*:div/*:div/*:div/*:script/*:script/*:div/*:div/*:script/*:script/*:div/*:div/*:script/*:script/*:div/*:div/*:h2/*:a/*:strong/*:p/*:div/*:a/*:strong/*:div/*:a/*:strong/*:div/*:div/*:div/*:script/*:script/*:div/*:div/*:h2/*:div/*:div/*:a/*:div/*:div/*:div/*:h3/*:p/*:div/*:a/*:div/*:div/*:div/*:h3/*:p/*:div/*:a/*:div/*:div/*:div/*:h3/*:p/*:div/*:a/*:div/*:div/*:div/*:h3/*:p/*:div/*:a/*:div/*:div/*:div/*:h3/*:p/*:div/*:a/*:div/*:div/*:div/*:h3/*:p/*:div/*:a/*:div/*:div/*:div/*:h3/*:p/*:div/*:a/*:div/*:div/*:div/*:div/*:div/*:span/*:span/*:span/*:h3/@class) [1.0-ml]
$config = json:object(<json:object xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:json="http://marklogic.com/xdmp/json"><json:entry key="element-qname-from-json-name"><json:value xsi:t...</json:object>...XDMP-ATOMIZEFUNC: (err:FOTY0013) Functions cannot be atomized...)
$a = fn:doc("/content/rss/72eb9bf835521446be8d2176e1ac9d22.xml")/newsitem/article/*:html/*:head/*:script[5]/*:script/*:script/*:script/*:link/*:script/*:script/*:script/*:script/*:script/*:script/*:style/*:script/*:script/*:script/*:script/*:scr
format-xml
和 format-json
选项 cts.search()
按这些格式过滤搜索结果;他们不做任何转换(参见 cts.search()
options documentation)。
有很多方法可以使用 MarkLogic 将 XML 转换为 JSON;最简单的可能是 json
XQuery library, specifically json:transform-to-json-object()
。您可以像这样在服务器端 JS 中使用该库:
var json = require('/MarkLogic/json/json.xqy');
var doc = cts.doc('/triplestore/97a5ab126bddeea0.xml');
var jsonDoc = json.transformToJsonObject(doc, json.config('custom'));
您可以使用 json.config()
配置和自定义转换。
cts.search()
returns 一个 Iterator
,所以你需要一个 for-of
循环(或某种累加器函数)来获得实际的 XML 文档,然后您可以对其进行转换。
更新:
该错误可能是 JSON 库中的错误,但那是一个非常深的 HTML 路径;而且我认为将 HTML 元素转换为 JSON 对象属性没有多大意义。相反,我们将序列化 HTML,并将字符串添加回我们的 JSON 对象。
这是一个搜索结果转换示例;显示如何解包 Iterator
、自定义 JSON 转换、序列化 XHTML 内容以便在 JSON 中使用等
备注:
- 这使用
fn.subsequence
将 Iterator
限制为前 10 个结果。
- 我正在将排除的
<html/>
元素序列化为字符串(使用 xpath()
method of the Node object and xdmp.quote()
,并将其作为 escapedContent
添加到 JSON 对象。
这是组合示例;你可以在 MarkLogic QConsole 中 运行 这个:
var json = require('/MarkLogic/json/json.xqy');
var conf = json.config('custom');
var htmlNs = 'http://www.w3.org/1999/xhtml';
// exclude <html:html/> elements
// Note: this is a little awkward because the JSON library is XQuery
// and requires an XDM sequence, not an Array
conf['ignore-element-names'] = json.arrayValues([
fn.QName(htmlNs, 'html')
]);
var results = fn.subsequence(
cts.search(cts.andQuery(null), 'format-xml'),
1,
10
);
var transformedResults = [];
var transformed = [];
for (var result of results) {
// transformToJson() returns an object-node() wrapped in a document-node()
// convert it to a regular JS object
transformed = json.transformToJson(result, conf).toObject()
transformed.escapedContent = xdmp.quote(
result.xpath('.//html:html', { html: htmlNs})
);
transformedResults.push(transformed);
}
transformedResults
我正在尝试使用 2 层服务器端 javascript 应用程序 return JSON 格式的 XML 文档。我知道 MarkLogic 可以使用 REST api 在 JSON 和 XML 格式之间轻松切换。
然而,下面returnsxml:
cts.search('something', ['format-xml']) // options may be omitted
但这return没什么:
cts.search('something', ['format-json'])
根据文档,我认为我已经正确使用了该功能。
这是否可以使用服务器端 javascript?
更新:
使用transformToJsonObject
如下:
var json = require('/MarkLogic/json/json.xqy');
var doc = fn.doc('/content/rss/72eb9bf835521446be8d2176e1ac9d22.xml')
var jsonDoc = json.transformToJsonObject(doc, json.config('custom'));
jsonDoc
我收到以下错误:
500 Internal Server Error
XDMP-Whosebug: Stack overflow
in /MarkLogic/json/custom.xqy, at 493:23,
in json-custom:is-ignore-attribute#2(json:object(<json:object xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:json="http://marklogic.com/xdmp/json"><json:entry key="element-qname-from-json-name"><json:value xsi:t...</json:object>...XDMP-ATOMIZEFUNC: (err:FOTY0013) Functions cannot be atomized...), fn:doc("/content/rss/72eb9bf835521446be8d2176e1ac9d22.xml")/newsitem/article/*:html/*:head/*:script[5]/*:script/*:script/*:script/*:link/*:script/*:script/*:script/*:script/*:script/*:script/*:style/*:script/*:script/*:script/*:script/*:script/*:script/*:script/*:script/*:script/*:script/*:link/*:script/*:script/*:noscript/*:link/*:meta/*:body/*:div/*:div/*:div/*:script/*:div/*:div/*:script/*:script/*:div/*:div/*:script/*:script/*:script/*:script/*:noscript/*:p/*:header/*:div/*:div/*:div/*:a/*:section/*:div/*:h2/*:ul/*:li/*:a/*:li/*:a/*:div/*:div/*:a/*:img/*:span/*:script/*:nav/*:div/*:h2/*:ul/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:li/*:a/*:span/*:div/*:a/*:form/*:div/*:label/*:div/*:script/*:div/*:div/*:div/*:div/*:div/*:a/*:svg/*:title/*:h2/*:a/*:div/*:button/*:div/*:ul/*:li/*:a/*:span/*:li/*:a/*:span/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:div/*:nav/*:a/*:span/*:span/*:ul/*:li/*:a/*:span/*:li/*:a/*:span/*:span/*:div/*:div/*:script/*:script/*:div/*:div/*:span/*:span/*:a/*:div/*:div/*:script/*:script/*:div/*:div/*:div/*:span/*:span/*:a/*:div/*:div/*:script/*:script/*:div/*:div/*:div/*:div/*:h1/*:div/*:ul/*:li/*:div/*:li/*:span/*:a/*:div/*:figure/*:span/*:img/*:span/*:span/*:figcaption/*:span/*:span/*:p/*:p/*:p/*:p/*:p/*:div/*:div/*:script/*:script/*:h2/*:p/*:p/*:figure/*:span/*:div/*:span/*:span/*:figcaption/*:span/*:span/*:p/*:p/*:p/*:p/*:p/*:p/*:p/*:p/*:div/*:a/*:h2/*:a/*:ul/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:li/*:a/*:span/*:div/*:div/*:div/*:h2/*:div/*:ul/*:li/*:a/*:div/*:div/*:div/*:span/*:div/*:div/*:li/*:a/*:div/*:div/*:div/*:span/*:div/*:div/*:li/*:a/*:div/*:div/*:div/*:span/*:div/*:div/*:li/*:a/*:div/*:div/*:div/*:span/*:div/*:div/*:li/*:a/*:div/*:div/*:div/*:span/*:div/*:div/*:li/*:a/*:div/*:div/*:div/*:span/*:div/*:div/*:li/*:a/*:div/*:div/*:div/*:span/*:div/*:div/*:li/*:a/*:div/*:div/*:div/*:span/*:div/*:div/*:li/*:a/*:div/*:div/*:div/*:span/*:div/*:div/*:div/*:div/*:div/*:h2/*:div/*:ul/*:li/*:div/*:div/*:a/*:div/*:span/*:p/*:div/*:div/*:div/*:div/*:script/*:script/*:div/*:div/*:script/*:script/*:div/*:div/*:script/*:script/*:div/*:div/*:h2/*:a/*:strong/*:p/*:div/*:a/*:strong/*:div/*:a/*:strong/*:div/*:div/*:div/*:script/*:script/*:div/*:div/*:h2/*:div/*:div/*:a/*:div/*:div/*:div/*:h3/*:p/*:div/*:a/*:div/*:div/*:div/*:h3/*:p/*:div/*:a/*:div/*:div/*:div/*:h3/*:p/*:div/*:a/*:div/*:div/*:div/*:h3/*:p/*:div/*:a/*:div/*:div/*:div/*:h3/*:p/*:div/*:a/*:div/*:div/*:div/*:h3/*:p/*:div/*:a/*:div/*:div/*:div/*:h3/*:p/*:div/*:a/*:div/*:div/*:div/*:div/*:div/*:span/*:span/*:span/*:h3/@class) [1.0-ml]
$config = json:object(<json:object xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:json="http://marklogic.com/xdmp/json"><json:entry key="element-qname-from-json-name"><json:value xsi:t...</json:object>...XDMP-ATOMIZEFUNC: (err:FOTY0013) Functions cannot be atomized...)
$a = fn:doc("/content/rss/72eb9bf835521446be8d2176e1ac9d22.xml")/newsitem/article/*:html/*:head/*:script[5]/*:script/*:script/*:script/*:link/*:script/*:script/*:script/*:script/*:script/*:script/*:style/*:script/*:script/*:script/*:script/*:scr
format-xml
和 format-json
选项 cts.search()
按这些格式过滤搜索结果;他们不做任何转换(参见 cts.search()
options documentation)。
有很多方法可以使用 MarkLogic 将 XML 转换为 JSON;最简单的可能是 json
XQuery library, specifically json:transform-to-json-object()
。您可以像这样在服务器端 JS 中使用该库:
var json = require('/MarkLogic/json/json.xqy');
var doc = cts.doc('/triplestore/97a5ab126bddeea0.xml');
var jsonDoc = json.transformToJsonObject(doc, json.config('custom'));
您可以使用 json.config()
配置和自定义转换。
cts.search()
returns 一个 Iterator
,所以你需要一个 for-of
循环(或某种累加器函数)来获得实际的 XML 文档,然后您可以对其进行转换。
更新:
该错误可能是 JSON 库中的错误,但那是一个非常深的 HTML 路径;而且我认为将 HTML 元素转换为 JSON 对象属性没有多大意义。相反,我们将序列化 HTML,并将字符串添加回我们的 JSON 对象。
这是一个搜索结果转换示例;显示如何解包 Iterator
、自定义 JSON 转换、序列化 XHTML 内容以便在 JSON 中使用等
备注:
- 这使用
fn.subsequence
将Iterator
限制为前 10 个结果。 - 我正在将排除的
<html/>
元素序列化为字符串(使用xpath()
method of the Node object andxdmp.quote()
,并将其作为escapedContent
添加到 JSON 对象。
这是组合示例;你可以在 MarkLogic QConsole 中 运行 这个:
var json = require('/MarkLogic/json/json.xqy');
var conf = json.config('custom');
var htmlNs = 'http://www.w3.org/1999/xhtml';
// exclude <html:html/> elements
// Note: this is a little awkward because the JSON library is XQuery
// and requires an XDM sequence, not an Array
conf['ignore-element-names'] = json.arrayValues([
fn.QName(htmlNs, 'html')
]);
var results = fn.subsequence(
cts.search(cts.andQuery(null), 'format-xml'),
1,
10
);
var transformedResults = [];
var transformed = [];
for (var result of results) {
// transformToJson() returns an object-node() wrapped in a document-node()
// convert it to a regular JS object
transformed = json.transformToJson(result, conf).toObject()
transformed.escapedContent = xdmp.quote(
result.xpath('.//html:html', { html: htmlNs})
);
transformedResults.push(transformed);
}
transformedResults