1
let $d := doc('/test/a-false.json')
return ($d, if ($d/a) then 'false is true' else 'false is false')

The result:

{"a":false}
false is true

Really?

StackOverflow's robot was not contented with the above, so I will add some meaningless text that you don't have to read, even though I think the above is more than adequate at describing the problem. Long live our mechanical overlords.

  • I'm afraid MarkLogic has deviated from the W3C standards in the way they handle JSON. They do some kind of implicit mapping of JSON into an XML tree structure: the details are a mystery to me as well. – Michael Kay May 20 '22 at 07:50
  • 1
    Yes, the MarkLogic support for JSON predates XQuery 3. It relies on the introduction of new node types to XDM (boolean-node() like here, array-node(), object-node(), etc.) – Florent Georges May 20 '22 at 10:13
  • Interesting. I agree with this post that JSONiq does a better job with syntax. https://stackoverflow.com/questions/44919443/what-are-the-differences-between-jsoniq-and-xquery-3-1 – miles zarathustra May 21 '22 at 00:16

1 Answers1

1

In your example $d/a is a boolean node, a MarkLogic extension, part of the set of node types added to represent JSON in XDM.

The EBV of such a node is true if it exists. Which might be surprising for a boolean node with the value false. What you see here is the answer to the question: "Does such a node exists?" For the question "Is its value false?," use fn:data().

Relevant expressions:

let $d := fn:doc('/test/a-false.json')
return (
  $d,
  $d/a,
  fn:data($d/a),
  if ( $d/a ) then 'false exists' else 'false does not exist',
  if ( fn:data($d/a) ) then 'false is true' else 'false is not true'
)

Result:

{"a":false}
fn:doc("/test/a-false.json")/boolean-node("a")
false
false exists
false is not true
Florent Georges
  • 2,190
  • 1
  • 15
  • 24
  • `xdmp:describe()` https://docs.marklogic.com/xdmp:describe can be helpful in "seeing" the difference between the selected `boolean-node()` and the boolean value: `$d/a ! xdmp:describe(.)` returns `fn:doc("/test.json")/boolean-node("a")` and `$d/a/data() ! xdmp:describe(.)` returns `fn:false()` – Mads Hansen May 20 '22 at 11:56
  • Yes, I understand what is happening. I think it is unfortunate that it was implemented this way, as it is an obstacle to usability. I would also argue that [] should test false (as it does in Groovy) but JavaScript disagrees. And of course if you're representing them as JS objects without any kind of customized boolean cast, all bets are off. The workaround I came up with was string($d/a)='true', but I guess data() may be a better idea. – miles zarathustra May 21 '22 at 00:09