Home > Software engineering >  skipping JSON property dynamically in MarkLogic XQuery
skipping JSON property dynamically in MarkLogic XQuery

Time:10-22

I want to call some existing code in my XQuery script in MarkLogic that takes a JSON as function parameter.

Depending on the input to my own code, I need to feed the other function a variant of the JSON so that it does contain an extra property or doesn't.

So far I only figured out to do this with code duplication:

let $json := 
  if (fn:exists($extraAttribute)) then
    object-node { 
      "query": array-node { $id },
      "extra": $extraAttribute
    }
  else
    object-node {
      "query": array-node { $id }
    }

Is there a more elegant way to solve this? With various values for "extra" the behaviour of the called code is different then without the property at all. So far I tried an empty sequence (), an empty string "" and null-node {} as alternative values.

UPDATE: The called code evaluates the JSON input like this:

let $extraStuff := $json/extra/fn:string()

I don't want to change the called code because I'm not the only caller and I don't know if others rely on that behaviour.

CodePudding user response:

Alternative #2:

Use the operator for object-node

let $extra := 
  if (fn:exists($extraAttribute)) then
    object-node { "extra": $extraAttribute }
  else
    object-node {}
    
let $data := object-node { 
      "query": array-node { $id }
    }
      $extra

I could not inline the $extra without an error, so I had to split it up like this.

CodePudding user response:

Alternative #1:

Use the json functions

import module namespace json = "http://marklogic.com/xdmp/json"
    at "/MarkLogic/json/json.xqy";


let $dataRaw := 
<json type="object" xmlns="http://marklogic.com/xdmp/json/basic">
  <query type="array">
    <item type="string">{$id}</item>
  </query>
  {
  if (fn:exists($extraAttribute)) then
    <extra type="string">{$extraAttribute}</extra>
  else
    ()
  }
</json>

let $config := json:config("full")
let $data := json:transform-to-json($dataRaw) ! object-node()

I needed to use the ! object-node() at the end because the called function expects an object-node but the json:transform-to-json produces a document-node with an object-node inside.

  • Related