I read XML exist as a test for a nonempty XQuery result. It doesn’t directly return the Boolean value inside that result. Even false() supplies a value, so its result exists.

Compare a node path with a Boolean expression
The query tests /r/n and false() against the same XML inputs. The first asks whether a selected node exists. The second supplies a Boolean value as the XQuery result.
The first document contains n, so both displayed outputs are one. That friendly row doesn’t expose the distinction by itself. I keep the document without n in the same example so the two expressions can disagree visibly.
WITH Documents AS
(
SELECT CaseId, CAST(XmlText AS nvarchar(200)) AS XmlText,
CAST(XmlText AS xml) AS XmlDocument
FROM (VALUES (1,N'<r><n>5</n></r>'),(2,N'<r/>'),
(3,CAST(NULL AS nvarchar(200)))) v(CaseId,XmlText)
)
SELECT CaseId, XmlText,
CAST(XmlDocument.exist('/r/n') AS int) AS NodePresent,
CAST(XmlDocument.exist('false()') AS int) AS BooleanResultExists
FROM Documents
ORDER BY CaseId;

Read the empty node sequence
The second document contains r without an n child. The node path returns an empty sequence, so NodePresent is zero. The false() expression still returns its Boolean value and therefore produces a nonempty result.
Its displayed existence result is one, even though that Boolean value is false. I’d retain this row when reviewing an XML condition. A Boolean-sounding name can conceal the distinction. Presence and the contents of a returned sequence are different questions.
Put the condition in a node predicate
When the requirement concerns a matching node, choose a path whose selected sequence is empty when nothing matches. A predicate on that path can express the intended condition while retaining existence semantics.
I wouldn’t wrap an arbitrary Boolean expression in exist and assume it behaves like a direct truth test. The query should make its selected nodes clear. That makes it easier to explain why a missing match produces zero instead of a Boolean item that still exists.

Preserve NULL XML input
The final row supplies a NULL XML instance. The method returns NULL for that input, and both derived columns retain it. A missing document is different from a supplied document with no matching child.
I’d keep that distinction when reporting incomplete input. Defaulting a missing document to an empty root can be a legitimate application rule, but it changes the meaning. Make that choice explicitly before the query instead of hiding it behind a convenient presence result.
Keep the result contract readable
The method returns bit, while the outer casts display these two teaching outputs as int. Their names distinguish node presence from the existence of a Boolean result. The original text remains beside them for inspection.
I avoid a vague alias such as ValidXml here. Both documents are already valid XML, and neither expression validates an application’s required fields. A narrowly named output helps prevent a presence check from being mistaken for a complete document-validation rule.
Review the path and namespace together
These small documents have no namespace and use one direct child name. A production document with a namespace needs a path that addresses that namespace correctly. Matching local-looking tag text alone doesn’t establish the same query contract.
The SELECT changes no document and defines no schema collection. I’d compare all three complete rows during validation, then add the exact namespace and predicate cases used by the application. A result for this path doesn’t prove that another path tests the intended business condition.
Keep the missing document and the empty document apart, and the checks stay honest.
An existing Boolean result is not its truth value, it is still a nonempty XQuery result.
Published by Pinal Dave on SQLAuthority. More of my work at pinaldave.com.
Discover more from SQL Authority with Pinal Dave
Subscribe to get the latest posts sent to your email.




