mirror of https://github.com/kdl-org/kdl.git
more prose
This commit is contained in:
parent
7739ca4d9d
commit
de203c658a
|
|
@ -1,8 +1,16 @@
|
||||||
# KDL Query Language Spec
|
# KDL Query Language Spec
|
||||||
|
|
||||||
This is loosely based on CSS selectors, but without the web-specific stuff.
|
The KDL Query Language is a small language specially tailored for querying KDL
|
||||||
|
documents to extract nodes and even specific data. It is loosely based on CSS
|
||||||
|
selectors for familiarity and ease of use. Think of it as CSS Selectors or
|
||||||
|
XPath, but for KDL!
|
||||||
|
|
||||||
## Selection operators
|
## Selectors
|
||||||
|
|
||||||
|
Selectors use selection operators to filter nodes that will be returned by an
|
||||||
|
API using KQL. The main differences between this and CSS selectors are the
|
||||||
|
lack of `*` (use `[]` instead), and the specific syntax for
|
||||||
|
[matchers](#matchers) (the stuff between `[` and `]`), which is similar, but not identical to CSS.
|
||||||
|
|
||||||
* `a > b`: Selects any `b` element that is a direct child of an `a` element.
|
* `a > b`: Selects any `b` element that is a direct child of an `a` element.
|
||||||
* `a b`: Selects any `b` element that is a _descendant_ of an `a` element.
|
* `a b`: Selects any `b` element that is a _descendant_ of an `a` element.
|
||||||
|
|
@ -15,10 +23,17 @@ This is loosely based on CSS selectors, but without the web-specific stuff.
|
||||||
|
|
||||||
## Matchers
|
## Matchers
|
||||||
|
|
||||||
|
Matchers are used to filter nodes by their various attributes (such as values,
|
||||||
|
properties, node names, etc). With the exception of `top()`, they are all used
|
||||||
|
inside a `[ ]` selector. Some matchers are unary, but most of them involve
|
||||||
|
binary operators.
|
||||||
|
|
||||||
* `top()`: Returns all toplevel children of the current document.
|
* `top()`: Returns all toplevel children of the current document.
|
||||||
* `top() > []`: Equivalent to `top()` on its own.
|
* `top() > []`: Equivalent to `top()` on its own.
|
||||||
* `[val()]`: Selects any element with a value.
|
* `[val()]`: Selects any element with a value.
|
||||||
* `[val(1)]`: Selects any element with a second value.
|
* `[val(1)]`: Selects any element with a second value.
|
||||||
|
* `[prop(foo)]`: Selects any element with a property named `foo`.
|
||||||
|
* `[prop]`: Selects any element with a property named `prop`.
|
||||||
|
|
||||||
Attribute matchers support certain binary operators:
|
Attribute matchers support certain binary operators:
|
||||||
|
|
||||||
|
|
@ -89,20 +104,28 @@ package {
|
||||||
|
|
||||||
Then the following queries are valid:
|
Then the following queries are valid:
|
||||||
|
|
||||||
* `package name` -> fetches the `name` node itself
|
* `package name`
|
||||||
* `top() > package name` -> fetches the `name` node, guaranteeing that `package` is in the document root.
|
* -> fetches the `name` node itself
|
||||||
* `dependencies` -> deep-fetches both `dependencies` nodes
|
* `top() > package name`
|
||||||
* `dependencies[platform]` -> fetches any dependencies nodes with a `platform` prop (just the one, in this case)
|
* -> fetches the `name` node, guaranteeing that `package` is in the document root.
|
||||||
* `dependencies[prop(platform)]` -> Identical to the above. Plain identifiers are equivalent to `prop(<identifier>)`.
|
* `dependencies`
|
||||||
* `dependencies > any()` -> fetches all direct-child nodes of any `dependencies`
|
* -> deep-fetches both `dependencies` nodes
|
||||||
nodes in the document. In this case, it will fetch both `miette` and
|
* `dependencies[platform]`
|
||||||
`winapi` nodes.
|
* -> fetches any dependencies nodes with a `platform` prop (just the one, in this case)
|
||||||
|
* `dependencies[prop(platform)]`
|
||||||
|
* -> Identical to the above. Plain identifiers are equivalent to `prop(<identifier>)`.
|
||||||
|
* `dependencies > []` ->
|
||||||
|
* fetches all direct-child nodes of any `dependencies` nodes in the
|
||||||
|
document. In this case, it will fetch both `miette` and `winapi` nodes.
|
||||||
|
|
||||||
There is an additional `=>` selector (called the "map selector") that MAY be
|
If using an API that supports the [map operator](#map-operator), the following
|
||||||
implemented, which will allow extracting/selecting arbitrary data _from_
|
are valid queries:
|
||||||
nodes, instead of returning the nodes themselves:
|
|
||||||
|
|
||||||
* `package name => val(0)` -> `["foo"]`. (The `0` is optional if you just want the first `val()`)
|
* `package name => val()`
|
||||||
* `dependencies[platform] => platform` -> `["windows"]`
|
* -> `["foo"]`.
|
||||||
* `dependencies > [] => (name(), val(), path)` -> `[("winapi", "1.0.0", "./crates/my-winapi-fork"), ("miette", "2.0.0", None)]`
|
* `dependencies[platform] => platform`
|
||||||
* `dependencies > [] => (name(), values(), props())` -> `[("winapi", ["1.0.0"], {"platform": "windows"}), ("miette", ["2.0.0"], {"dev": true})]`
|
* -> `["windows"]`
|
||||||
|
* `dependencies > [] => (name(), val(), path)`
|
||||||
|
* -> `[("winapi", "1.0.0", "./crates/my-winapi-fork"), ("miette", "2.0.0", None)]`
|
||||||
|
* `dependencies > [] => (name(), values(), props())`
|
||||||
|
* -> `[("winapi", ["1.0.0"], {"platform": "windows"}), ("miette", ["2.0.0"], {"dev": true})]`
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue