MarkLogic json:transform-from-json有多个名称空间?

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

在MarkLogic中,是否可以使用json:transform-from-json将json转换为具有多个名称空间的XML?例如,如何转换

{
  options: {
    format: "xml"
  }
}

<options xmlns="xdmp:http-get">
  <format xmlns="xdmp:document-get">xml</format>
</options>
json xquery marklogic
2个回答
1
投票

示例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)

1
投票

是的,你可以,它没有记录或简单,但它不是秘密。查看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的映射,并将其与您的自定义函数一起放在配置中。

通常需求更加困难,因此建议您尝试使用配置“关闭”然后发布流程。

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