Preserves Path is a language for selecting and filtering portions of a Preserves value. It has an associated schema describing the various kinds of Path expressions as abstract syntax.
Preserves Path expressions come in several flavours: selectors, steps (axes and filters), and predicates. Each is described below along with its abstract syntax definitions.
Selectors are a sequence of steps, applied one after the other to the currently-selected value. Each step transforms an input into zero or more outputs. A step is an axis or a filter.
Selector = [Step ...] . Step = Axis / Filter .
Each axis step generally selects some sub-portion or -portions of the current document. An
axis may also have a secondary filtering effect: for example,
label only applies to Records,
and will yield an empty result set when applied to any other kind of input.
Axis = / <values> ;; yields the immediate subvalues of the input nonrecursively / <descendants> ;; recurses through all descendant subvalues of the input / <at @key any> ;; extracts a subvalue named by the given key, if any / <label> ;; extracts a Record's label, if any / <keys> ;; extracts all keys (for subvalues) of the input, nonrecursively / <length> ;; extracts the length/size of the input, if any / <annotations> ;; extracts all annotations attached to the input / <embedded> ;; moves into the representation of an embedded value, if any / <parse @module [symbol ...] @name symbol> ;; parses using Preserves Schema / <unparse @module [symbol ...] @name symbol> ;; unparses using Preserves Schema .
unparse variants name Schema definitions,
to be resolved by the eventual surrounding context in which the expression will be executed. A
parse axis parses the input using a Schema definition; if the parse succeeds, the axis moves
into the parse result. Similarly,
unparse expects an abstract parse result, transforming it
back into a concrete value according to the Schema definition.
Each filter step generally applies some test to the current document as a whole, either emitting it unchanged (with exceptions, detailed below) or emitting no outputs at all.
Filter = / <nop> ;; Always emit the input / <compare @op Comparison @literal any> ;; Emit iff the comparison holds / <regex @regex string> ;; Emit iff input is String and regex matches / <test @pred Predicate> ;; Apply complex predicate / <real> ;; Emit iff input is Float, Double, or Integer / <int> ;; TRUNCATE and emit iff Float, Double or Integer / <kind @kind ValueKind> ;; Emit iff input kind matches .
The complex predicates in a
test filter are built up from logical connectives over selectors.
Selector predicate evaluates to true whenever, applied to its input, it results in a
non-empty output set.
Predicate = / Selector / <not @pred Predicate> / <or @preds [Predicate ...]> / <and @preds [Predicate ...]> .
compare filter includes a
Comparison and a literal value to compare the input against.
<compare eq 3> only produces an output if the input is equal (according to the
Preserves semantic model) to
Comparison = =eq / =ne / =lt / =ge / =gt / =le .
NB. For inequalities (
le), comparison between values of different kinds is
undefined in the current draft specification.
kind filter selects only values from one of the kinds of Preserves value:
ValueKind = / =Boolean / =Float / =Double / =SignedInteger / =String / =ByteString / =Symbol / =Record / =Sequence / =Set / =Dictionary / =Embedded .