jsonxmlxquerymarklogicmarklogic-10

Add element names dynamically to array-element-names configuration of json:transform-to-json() in Marklogic


I'm doing a cts:search and converting the result nodes to JSON using json:transform-to-json() function in MarkLogic 10.

Sample code:

let $config := json:config("custom")
let $response := cts:search(fn:doc(),$query)
return json:transform-to-json($response,$config)

The resultant XML nodes might have child elements with same name. I want these to be converted as array during conversion, so I need to fetch all the multiple child elements with same name and add the QName values as array-element-names config before the conversion.

The issue here is I won't be knowing the array child element names that would appear in the resultant XML nodes and also some results might have more number of child nodes(greater than 50 nodes).

Sample XML result node:

<meta>
      <id>draa066</id>
      <id>draa088</id>
      <xref rid="aff1" ref-type="aff"/>
      <xref rid="cor1" ref-type="corresp"/>
      <email>surowiec@mathematik.uni-marburg.de</email>
</meta>

Expected JSON output:

{
  "meta": {
    "id": [
      "draa066",
      "draa088"
    ],
    "xref": [
      "",
      ""
    ],
    "email": "surowiec@mathematik.uni-marburg.de"
  }
}

Please let me know on the possibility to do this.


Solution

  • I believe the following will work for you.

    Please note the example of 3 items on purpose. The middle one (no array) shows that the function signature of returning no results as a possibility alows the safe use of the array-element-names even when no result (because MarkLogic will not store map entries with no value)

    xquery version "1.0-ml";
    import module namespace json="http://marklogic.com/xdmp/json"
     at "/MarkLogic/json/json.xqy";
    
    declare function local:get-duplicate-element-names($doc) as xs:QName* {
      fn:distinct-values(for $node in $doc/meta/node()
        let $name := fn:node-name($node)
        where fn:count($doc/meta/node()[fn:node-name(.) = $name]) > 1
        return $name)
    };
    
    
    let $responses := (
      document{
        <meta>
              <id>draa066</id>
              <id>draa088</id>
              <xref rid="aff1" ref-type="aff"/>
              <xref rid="cor1" ref-type="corresp"/>
              <email>surowiec@mathematik.uni-marburg.de</email>
        </meta>
      },
      document{  
        <meta>
              <id>draa088</id>
              <xref rid="aff1" ref-type="aff"/>
              <email>surowiec@mathematik.uni-marburg.de</email>
        </meta>
      },
      document{
        <meta>
              <id>draa066</id>
              <xref rid="aff1" ref-type="aff"/>
              <xref rid="cor1" ref-type="corresp"/>
              <email>surowiec@mathematik.uni-marburg.de</email>
        </meta>
      }
    )
    
    let $config := json:config("custom")
    
    return for $response in $responses
      return json:transform-to-json($response,$config=>map:with("array-element-names", local:get-duplicate-element-names($response)))
    

    Results:

       {
          "meta":{
             "id":[
                "draa066",
                "draa088"
             ],
             "xref":[
                {
                   "rid":"aff1",
                   "ref-type":"aff"
                },
                {
                   "rid":"cor1",
                   "ref-type":"corresp"
                }
             ],
             "email":"surowiec@mathematik.uni-marburg.de"
          }
       }
       
       {
          "meta":{
             "id":"draa088",
             "xref":{
                "rid":"aff1",
                "ref-type":"aff"
             },
             "email":"surowiec@mathematik.uni-marburg.de"
          }
       }
       
       {
          "meta":{
             "id":"draa066",
             "xref":[
                {
                   "rid":"aff1",
                   "ref-type":"aff"
                },
                {
                   "rid":"cor1",
                   "ref-type":"corresp"
                }
             ],
             "email":"surowiec@mathematik.uni-marburg.de"
          }
       }