Merge branch 'main' into patch-1

This commit is contained in:
Kat Marchán 2021-09-11 20:46:07 -07:00 committed by GitHub
commit 4196ca328e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 105 additions and 27 deletions

View File

@ -24,12 +24,14 @@ lack of `*` (use `[]` instead), and the specific syntax for
## 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
properties, node names, etc). With the exception of `top()` and `()`, 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() > []`: Equivalent to `top()` on its own.
* `(foo)`: Selects any element with a tag named `foo`.
* `()`: Selects any element with any tag.
* `[val()]`: Selects any element with a value.
* `[val(1)]`: Selects any element with a second value.
* `[prop(foo)]`: Selects any element with a property named `foo`.
@ -41,9 +43,10 @@ Attribute matchers support certain binary operators:
* `[prop(name) = 1]`: Selects any element with a property `name` whose value is 1.
* `[name = 1]`: Equivalent to the above.
* `[name() = "hi"]`: Selects any element whose _node name_ is "hi". Equivalent to just `hi`, but more useful when using string operators.
* `[tag() = "hi"]`: Selects any element whose tag is "hi". Equivalent to just `(hi)`, but more useful when using string operators.
* `[val() != 1]`: Selects any element whose first value exists, and is not 1.
The following operators work with any `val()`, `prop()`, or `name()` values.
The following operators work with any `val()` or `prop()` values.
If the value is not of the same type, the operator will always fail ("1" is
never coerced to 1, and there is no "universal" ordering across all types.):
@ -52,12 +55,18 @@ never coerced to 1, and there is no "universal" ordering across all types.):
* `[val() < 1]`: Selects any element whose first value is less than 1.
* `[val() <= 1]`: Selects any element whose first value is less than or equal to 1.
The following operators work only with string `val()`, `prop()`, or `name()` values. If the value is not a string, the matcher will always fail:
The following operators work only with string `val()`, `prop()`, `tag()`, or `name()` values.
If the value is not a string, the matcher will always fail:
* `[val() ^= "foo"]`: Selects any element whose first value starts with "foo".
* `[val() $= "foo"]`: Selects any element whose first value ends with "foo".
* `[val() *= "foo"]`: Selects any element whose first value contains "foo".
The following operators work only with `val()` or `prop()` values. If the value
is not one of those, the matcher will always fail:
* `[val() = (foo)]`: Selects any element whose tag is "foo".
## Map Operator
KQL implementations MAY support a "map operator", `=>`, that allows selection

View File

@ -33,6 +33,9 @@ None.
* [`definitions`](#definitions-node) (optional): Definitions of nodes, values, props, and children block to reference in the toplevel nodes.
* `node-names` (optional): [Validations](#validation-nodes) to apply to the _names_ of child nodes.
* `other-nodes-allowed` (optional): Whether to allow nodes other than the ones explicitly listed here. Defaults to `false`.
* [`tag`](#tag-node) - zero or more toplevel tags for nodes in the KDL document that this schema describes.
* `tag-names` (optional): [Validations](#validation-nodes) to apply to the _names_ of tags of child nodes.
* `other-tags-allowed` (optional): Whether to allow node tags other than the ones explicitly listed here. Defaults to `false`.
### `info` node
@ -161,7 +164,7 @@ another node.
* `description` (optional): An informational description of the purpose of this node.
* `id` (optional): A globally unique identifier for this node.
* `ref` (optional): A globally unique reference to another node's ID. If present, all properties, values, and children defined in the target node will be copied to this node, replacing any conflicts.
* `ref` (optional): A [KDL Query](./QUERY-SPEC.md) string relative to the root of the document. If present, all properties, values, and children defined in the target node will be copied to this node, replacing any conflicts.
#### Children
@ -169,10 +172,31 @@ another node.
* `max` (optional): Maximum number of this kind of node (or any node, if the name is missing) allowed in the parent's children block.
* `prop-names` (optional): [Validations](#validation-nodes) to apply to the _names_ of properties.
* `other-props-allowed` (optional): Whether to allow props other than the ones explicitly listed here. Defaults to `false`.
* `tag`: [Validations](#validation-nodes) to apply to the tag of the node.
* [`prop`](#prop-node) - zero or more properties for this node.
* [`value`](#value-node) - zero or more values for this node.
* [`children`](#children-node) - zero or more children for this node.
### `tag` node
The `tag` describes the tags allowed in a children block or toplevel document.
#### Values
* Tag name (optional) - A tag for the node. If present, the node's rules/validations will apply only to children with this tag. Otherwise, the rules will apply to _all_ child nodes with tags.
#### Properties
* `description` (optional): An informational description of the purpose of this node.
* `id` (optional): A globally unique identifier for this node.
* `ref` (optional): A [KDL Query](./QUERY-SPEC.md) string relative to the root of the document. If present, all properties, values, and children defined in the target node will be copied to this node, replacing any conflicts.
#### Children
* [`node`](#node-node) - zero or more toplevel nodes that this tag is allowed to be on.
* `node-names` (optional): [Validations](#validation-nodes) to apply to the _names_ of nodes with this tag.
* `other-nodes-allowed` (optional): Whether to allow nodes other than the ones explicitly listed here. Defaults to `false`.
### `prop` node
Represents a property of a node, which is a key/value pair in KDL.
@ -185,7 +209,7 @@ Represents a property of a node, which is a key/value pair in KDL.
* `description` (optional): An informational description of the purpose of this property.
* `id` (optional): A globally unique identifier for this property.
* `ref` (optional): A globally unique reference to another property's ID. If present, all properties defined in the target property will be copied to this property, replacing any conflicts.
* `ref` (optional): A [KDL Query](./QUERY-SPEC.md) string relative to the root of the document. If present, all properties defined in the target property will be copied to this property, replacing any conflicts.
#### Children
@ -204,7 +228,7 @@ None.
* `description` (optional): An informational description of the purpose of this value.
* `id` (optional): A globally unique identifier for this value.
* `ref` (optional): A globally unique reference to another value's ID. If present, all values defined in the target value will be copied to this value, replacing any conflicts.
* `ref` (optional): A [KDL Query](./QUERY-SPEC.md) string relative to the root of the document. If present, all values defined in the target value will be copied to this value, replacing any conflicts.
#### Children
@ -224,7 +248,7 @@ None.
* `description` (optional): An informational description of the purpose of this children block.
* `id` (optional): A globally unique identifier for this children block.
* `ref` (optional): A globally unique reference to another children block's ID. If present, all children defined in the target children block will be copied to this children block, replacing any conflicts.
* `ref` (optional): A [KDL Query](./QUERY-SPEC.md) string relative to the root of the document. If present, all children defined in the target children block will be copied to this children block, replacing any conflicts.
#### Children
@ -240,6 +264,7 @@ and property names when the `node-names` or `prop-names` options are activated.
#### Generic validations
* `tag`: [Validations](#validation-nodes) to apply to the tag of the value.
* `type`: A string denoting the type of the property value.
* `enum`: A specific list of allowed values for this property. May be heterogenous as long as it agrees with the `type`, if specified.
@ -272,6 +297,7 @@ and property names when the `node-names` or `prop-names` options are activated.
* `uuid`: RFC4122 UUID.
* `regex`: Regular expression. Specific patterns may be implementation-dependent.
* `base64`: A Base64-encoded string, denoting arbitrary binary data.
* `kdl-query`: A [KDL Query](./QUERY-SPEC.md) string.
#### Number validations
@ -311,6 +337,7 @@ None.
#### Children
* [`node`](#node-node) - zero or more node definitions.
* [`tag`](#tag-node) - zero or more toplevel tags for nodes in the KDL document that this schema describes.
* [`prop`](#prop-node) - zero or more property definitions.
* [`value`](#value-node) - zero or more value definitions.
* [`children`](#children-node) - zero or more definitions of children blocks.

View File

@ -432,7 +432,7 @@ bare-identifier := ((identifier-char - digit - sign) identifier-char* | sign ((i
identifier-char := unicode - linespace - [\/(){}<>;[]=,"]
keyword := boolean | 'null'
prop := identifier '=' value
value := (type ws*)? (string | number | keyword)
value := type? (string | number | keyword)
type := '(' identifier ')'
string := raw-string | escaped-string

View File

@ -19,10 +19,21 @@ document {
min 1
max 1
children id="node-children" {
node "node-names" description="Validations to apply specifically to arbitrary node names" {
children ref="#validations"
node "node-names" id="node-names-node" description="Validations to apply specifically to arbitrary node names" {
children ref=r#"[id="validations"]"#
}
node "other-nodes-allowed" description="Whether to allow child nodes other than the ones explicitly listed. Defaults to 'false'." {
node "other-nodes-allowed" id="other-nodes-allowed-node" description="Whether to allow child nodes other than the ones explicitly listed. Defaults to 'false'." {
max 1
value {
min 1
max 1
type "boolean"
}
}
node "tag-names" description="Validations to apply specifically to arbitrary type tag names" {
children ref=r#"[id="validations"]"#
}
node "other-tags-allowed" description="Whether to allow child node tags other than the ones explicitly listed. Defaults to 'false'." {
max 1
value {
min 1
@ -48,7 +59,7 @@ document {
min 1
max 1
}
prop ref="#info-lang"
prop ref=r#"[id="info-lang"]"#
}
node "author" description="Author of the schema" {
value id="info-person-name" description="Person name" {
@ -61,12 +72,12 @@ document {
pattern r"\d{4}-\d{4}-\d{4}-\d{4}"
}
children {
node ref="#info-link"
node ref=r#"[id="info-link"]"#
}
}
node "contributor" description="Contributor to the schema" {
value ref="#info-person-name"
prop ref="#info-orcid"
value ref=r#"[id="info-person-name"]"#
prop ref=r#"[id="info-orcid"]"#
}
node "link" id="info-link" description="Links to itself, and to sources describing it" {
value description="A URL that the link points to" {
@ -79,7 +90,7 @@ document {
type "string"
enum "self" "documentation"
}
prop ref="#info-lang"
prop ref=r#"[id="info-lang"]"#
}
node "license" description="The license(s) that the schema is licensed under" {
value description="Name of the used license" {
@ -91,7 +102,7 @@ document {
type "string"
}
children {
node ref="#info-link"
node ref=r#"[id="info-link"]"#
}
}
node "published" description="When the schema was published" {
@ -113,7 +124,7 @@ document {
min 1
max 1
}
prop ref="#info-time"
prop ref=r#"[id="info-time"]"#
}
node "version" description="The version number of this version of the schema" {
value description="Semver version number" {
@ -125,6 +136,27 @@ document {
}
}
}
node "tag" id="tag-node" description="A tag belonging to a child node of `document` or another node." {
value description="The name of the tag. If a tag name is not supplied, the node rules apply to _all_ nodes belonging to the parent." {
type "string"
max 1
}
prop "description" description="A description of this node's purpose." {
type "string"
}
prop "id" description="A globally-unique ID for this node." {
type "string"
}
prop "ref" description="A globally unique reference to another node." {
type "string"
format "kdl-query"
}
children {
node ref=r#"[id="node-names-node"]"#
node ref=r#"[id="other-nodes-allowed-node"]"#
node ref=r#"[id="node-node"]"#
}
}
node "node" id="node-node" description="A child node belonging either to `document` or to another `node`. Nodes may be anonymous." {
value description="The name of the node. If a node name is not supplied, the node rules apply to _all_ nodes belonging to the parent." {
type "string"
@ -138,10 +170,11 @@ document {
}
prop "ref" description="A globally unique reference to another node." {
type "string"
format "kdl-query"
}
children {
node "prop-names" description="Validations to apply specifically to arbitrary property names" {
children ref="#validations"
children ref=r#"[id="validations"]"#
}
node "other-props-allowed" description="Whether to allow properties other than the ones explicitly listed. Defaults to 'false'." {
max 1
@ -167,6 +200,7 @@ document {
type "number"
}
}
node ref=r#"[id="value-tag-node"]"#
node "prop" id="prop-node" description="A node property key/value pair." {
value description="The property key." {
type "string"
@ -176,6 +210,7 @@ document {
}
prop "ref" description="A globally unique reference to another property node." {
type "string"
format "kdl-query"
}
prop "description" description="A description of this property's purpose." {
type "string"
@ -191,6 +226,10 @@ document {
}
}
children id="validations" description="General value validations." {
node "tag" id="value-tag-node" description="The tags associated with this value" {
max 1
children ref="[id="validations"]"
}
node "type" description="The type for this prop's value." {
max 1
value {
@ -230,7 +269,7 @@ document {
min 1
type "string"
// https://json-schema.org/understanding-json-schema/reference/string.html#format
enum "date-time" "date" "time" "duration" "decimal" "currency" "country-2" "country-3" "country-subdivision" "email" "idn-email" "hostname" "idn-hostname" "ipv4" "ipv6" "uri" "uri-reference" "iri", "iri-reference" "uri-template" "regex" "uuid" "i8" "i16" "i32" "i64" "u8" "u16" "u32" "u64" "isize" "usize" "f32" "f64" "decimal64" "decimal128"
enum "date-time" "date" "time" "duration" "decimal" "currency" "country-2" "country-3" "country-subdivision" "email" "idn-email" "hostname" "idn-hostname" "ipv4" "ipv6" "uri" "uri-reference" "iri", "iri-reference" "uri-template" "regex" "uuid" "kdl-query" "i8" "i16" "i32" "i64" "u8" "u16" "u32" "u64" "isize" "usize" "f32" "f64" "decimal64" "decimal128"
}
}
node "%" description="Only used for numeric values. Constrains them to be multiples of the given number(s)" {
@ -280,11 +319,12 @@ document {
}
prop "ref" description="A globally unique reference to another value node." {
type "string"
format "kdl-query"
}
prop "description" description="A description of this property's purpose." {
type "string"
}
children ref="#validations"
children ref=r#"[id="validations"]"#
children description="Node value-specific validations" {
node "min" description="minimum number of values for this node." {
max 1
@ -310,20 +350,22 @@ document {
}
prop "ref" description="A globally unique reference to another children node." {
type "string"
format "kdl-query"
}
prop "description" description="A description of this these children's purpose." {
type "string"
}
children ref="#node-children"
children ref=r#"[id="node-children"]"#
}
}
}
node "definitions" description="Definitions to reference in parts of the top-level nodes" {
children {
node ref="#node-node"
node ref="#value-node"
node ref="#prop-node"
node ref="#children-node"
node ref=r#"[id="node-node"]"#
node ref=r#"[id="value-node"]"#
node ref=r#"[id="prop-node"]"#
node ref=r#"[id="children-node"]"#
node ref=r#"[id="tag-node"]"#
}
}
}