Search code examples
jsonxquerymarklogic

MarkLogic json:transform-from-json with multiple namespaces?


In MarkLogic, is it possible to use json:transform-from-json to convert json into XML with multiple namespaces? For example, how to convert

{
  options: {
    format: "xml"
  }
}

into

<options xmlns="xdmp:http-get">
  <format xmlns="xdmp:document-get">xml</format>
</options>

Solution

  • There is nothing in the example JSON that would indicate that those namespaces should be applied to the XML elements.

    If you use json:transform-from-json() the resulting XML will be in the http://marklogic.com/xdmp/json/basic namespace.

    <json type="object" xmlns="http://marklogic.com/xdmp/json/basic">
      <options type="object">
        <format type="string">xml</format>
      </options>
    </json>
    

    You would then need to transform that XML in order to get those elements in the desired namespaces. One way to do that would be with a recursive typeswitch function:

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

    However, if you are attempting to construct the XML in order to build options for xdmp:document-get(), you might that it is easier to specify the options using a map:map instead of the XML form.

    Options with which to customize this operation. You can specify options as either an XML element in the "xdmp:document-get" namespace, or as a map:map. The options names below are XML element localnames. When using a map, replace the hyphens with camel casing. For example, "an-option" becomes "anOption" when used as a map:map key.

    If you have the JSON object, you can select the options property and then use fn:data() or xdmp:from-json() to atomize the options object-node as a map:

    fn:data($json//options)