forEachNodeIn

fun forEachNodeIn(document: Variant, limits: JsonPathLimits = this.limits, sink: (VariantNode) -> Unit)

Every node document holds at this query's locations, in RFC 9535's nodelist order.

A sink, not a Sequence, and for the same reason CatalogPath.forEachNodeIn is one. VariantNode.value is a view over the bytes it was built from, so a lazy sequence would let one escape the snapshot that maps them — a read of freed memory, or on Windows a mapping that then cannot be unmapped. The nodes are valid for the duration of the call; anything kept beyond it must be copied, with Variant.toByteArray. VariantNode.location is an ordinary value and outlives everything.

The walk still carries no budget that truncates, and must not acquire one: a short nodelist is a wrong answer with nothing to say so. What it carries is a budget that refuses — limits, or limits overridden here — which raises JsonPathLimitExceededException and delivers nothing rather than delivering part of an answer. The two are opposite mechanisms and the distinction is the whole of why this is safe: a caller that catches the exception knows it has no answer, where a caller handed a truncated nodelist cannot tell it from a small document. The bounds on the query — 1024 selectors, 64 levels of nesting — are separate again, and compile applies those.

Nodes already handed to sink before a limit is met are not an answer and must not be treated as one; the exception says the evaluation was abandoned, not that it finished early.

Parameters

limits

overrides the query's own for this call. Pass JsonPathLimits.NONE to evaluate a trusted query over a document known to be large.

Throws

if the evaluation costs more than limits allows.

if the document's bytes do not decode. A value the engine cannot read is reported, never skipped.