在MarkLogic中,是否可以使用json:transform-from-json将json转换为具有多个名称空间的XML?例如,如何转换
{
options: {
format: "xml"
}
}
成
<options xmlns="xdmp:http-get">
<format xmlns="xdmp:document-get">xml</format>
</options>
示例JSON中没有任何内容表明这些名称空间应该应用于XML元素。
如果使用json:transform-from-json()
,生成的XML将位于http://marklogic.com/xdmp/json/basic
名称空间中。
<json type="object" xmlns="http://marklogic.com/xdmp/json/basic">
<options type="object">
<format type="string">xml</format>
</options>
</json>
然后,您需要转换该XML,以便在所需的命名空间中获取这些元素。一种方法是使用递归typeswitch函数:
xquery version "1.0-ml";
declare namespace j = "http://marklogic.com/xdmp/json/basic";
import module namespace json="http://marklogic.com/xdmp/json"
at "/MarkLogic/json/json.xqy";
declare function local:convert($node as node()) as item()* {
typeswitch($node)
case attribute() return ()
case element(j:json) return local:convert($node/node())
case element(j:options) return element {fn:QName("xdmp:http-get", $node/local-name())} {local:convert($node/node())}
case element() return element {fn:QName("xdmp:document-get", $node/local-name())} {local:convert($node/node())}
default return $node
};
let $json := '{
options: {
format: "xml"
}
}'
return local:convert(json:transform-from-json( $json ))
但是,如果您尝试构造XML以构建xdmp:document-get()
的选项,则可能更容易使用map:map
而不是XML表单来指定选项。
用于自定义此操作的选项。您可以将选项指定为“xdmp:document-get”命名空间中的XML元素,或者指定为
map:map
。以下选项名称是XML元素本地名称。使用地图时,请使用驼峰套管替换连字符。例如,当用作map:map键时,“an-option”变为“anOption”。
如果您有JSON对象,则可以选择options
属性,然后使用fn:data()
或xdmp:from-json()
将options
对象节点雾化为地图:
fn:data($json//options)
是的,你可以,它没有记录或简单,但它不是秘密。查看Modules / MarkLogic / json / custom.xqy中的源代码
然后记录更多自定义参数。 “有趣的”允许您覆盖用于转换的各个方法。示例:使用自定义策略时,您可以设置替代。以下是默认值,您可以更改它们。
map:put($c , $json-custom:element-qname-from-json-name , json-custom:element-qname-from-json-name#2 ),
map:put($c , $json-custom:attribute-qname-from-json-name , json-custom:attribute-qname-from-json-name#2 ),
用你自己的函数'json-custom:element-qname-from-json-name'替换 - 你可以使用你想要的任何逻辑,给定配置对象和当前的json字段名称,返回完整的QName。
您可以从上面的文件中提取“内置”功能(它没有被遮挡)。从版本9.0开始,这看起来像:
declare %private function json-custom:element-qname-from-json-name( $config as map:map , $json_name as xs:string? ) as xs:QName
{
json-custom:qname( map:get( $config , $json-custom:element-namespace ) ,
map:get( $config , $json-custom:element-namespace-prefix ) ,
if(map:get($config , $json-custom:camel-case)) then json-custom:from-camelCase($json_name) else $
};
为了做到这一点,这可能变得非常棘手。我建议结合自定义转换,然后进行xml后处理(使用xquery或xslt)。
棘手的部分是当你从JSON转向XML时你没有得到太多的“上下文”。 JSON没有节点祖先或订购。你得到的只是一个字段名称。如果你可以从那里映射到所需的QName,那么它很容易。例如,您可以创建一个json名称到QNames的映射,并将其与您的自定义函数一起放在配置中。
通常需求更加困难,因此建议您尝试使用配置“关闭”然后发布流程。