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
Matchers are used to filter nodes by their various attributes (such as values, 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 properties, node names, etc). With the exception of `top()` and `()`, they are all
inside a `[ ]` selector. Some matchers are unary, but most of them involve used inside a `[ ]` selector. Some matchers are unary, but most of them involve
binary operators. 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.
* `(foo)`: Selects any element with a tag named `foo`.
* `()`: Selects any element with any tag.
* `[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(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. * `[prop(name) = 1]`: Selects any element with a property `name` whose value is 1.
* `[name = 1]`: Equivalent to the above. * `[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. * `[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. * `[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 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.): 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 1.
* `[val() <= 1]`: Selects any element whose first value is less than or equal to 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 starts with "foo".
* `[val() $= "foo"]`: Selects any element whose first value ends with "foo". * `[val() $= "foo"]`: Selects any element whose first value ends with "foo".
* `[val() *= "foo"]`: Selects any element whose first value contains "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 ## Map Operator
KQL implementations MAY support a "map operator", `=>`, that allows selection 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. * [`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. * `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`. * `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 ### `info` node
@ -161,7 +164,7 @@ another node.
* `description` (optional): An informational description of the purpose of this node. * `description` (optional): An informational description of the purpose of this node.
* `id` (optional): A globally unique identifier for 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 #### 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. * `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. * `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`. * `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. * [`prop`](#prop-node) - zero or more properties for this node.
* [`value`](#value-node) - zero or more values for this node. * [`value`](#value-node) - zero or more values for this node.
* [`children`](#children-node) - zero or more children 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 ### `prop` node
Represents a property of a node, which is a key/value pair in KDL. 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. * `description` (optional): An informational description of the purpose of this property.
* `id` (optional): A globally unique identifier for 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 #### Children
@ -204,7 +228,7 @@ None.
* `description` (optional): An informational description of the purpose of this value. * `description` (optional): An informational description of the purpose of this value.
* `id` (optional): A globally unique identifier for 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 #### Children
@ -224,7 +248,7 @@ None.
* `description` (optional): An informational description of the purpose of this children block. * `description` (optional): An informational description of the purpose of this children block.
* `id` (optional): A globally unique identifier for 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 #### Children
@ -240,6 +264,7 @@ and property names when the `node-names` or `prop-names` options are activated.
#### Generic validations #### Generic validations
* `tag`: [Validations](#validation-nodes) to apply to the tag of the value.
* `type`: A string denoting the type of the property 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. * `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. * `uuid`: RFC4122 UUID.
* `regex`: Regular expression. Specific patterns may be implementation-dependent. * `regex`: Regular expression. Specific patterns may be implementation-dependent.
* `base64`: A Base64-encoded string, denoting arbitrary binary data. * `base64`: A Base64-encoded string, denoting arbitrary binary data.
* `kdl-query`: A [KDL Query](./QUERY-SPEC.md) string.
#### Number validations #### Number validations
@ -311,6 +337,7 @@ None.
#### Children #### Children
* [`node`](#node-node) - zero or more node definitions. * [`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. * [`prop`](#prop-node) - zero or more property definitions.
* [`value`](#value-node) - zero or more value definitions. * [`value`](#value-node) - zero or more value definitions.
* [`children`](#children-node) - zero or more definitions of children blocks. * [`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 - [\/(){}<>;[]=,"] identifier-char := unicode - linespace - [\/(){}<>;[]=,"]
keyword := boolean | 'null' keyword := boolean | 'null'
prop := identifier '=' value prop := identifier '=' value
value := (type ws*)? (string | number | keyword) value := type? (string | number | keyword)
type := '(' identifier ')' type := '(' identifier ')'
string := raw-string | escaped-string string := raw-string | escaped-string

View File

@ -19,10 +19,21 @@ document {
min 1 min 1
max 1 max 1
children id="node-children" { children id="node-children" {
node "node-names" description="Validations to apply specifically to arbitrary node names" { node "node-names" id="node-names-node" description="Validations to apply specifically to arbitrary node names" {
children ref="#validations" 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 max 1
value { value {
min 1 min 1
@ -48,7 +59,7 @@ document {
min 1 min 1
max 1 max 1
} }
prop ref="#info-lang" prop ref=r#"[id="info-lang"]"#
} }
node "author" description="Author of the schema" { node "author" description="Author of the schema" {
value id="info-person-name" description="Person name" { value id="info-person-name" description="Person name" {
@ -61,12 +72,12 @@ document {
pattern r"\d{4}-\d{4}-\d{4}-\d{4}" pattern r"\d{4}-\d{4}-\d{4}-\d{4}"
} }
children { children {
node ref="#info-link" node ref=r#"[id="info-link"]"#
} }
} }
node "contributor" description="Contributor to the schema" { node "contributor" description="Contributor to the schema" {
value ref="#info-person-name" value ref=r#"[id="info-person-name"]"#
prop ref="#info-orcid" prop ref=r#"[id="info-orcid"]"#
} }
node "link" id="info-link" description="Links to itself, and to sources describing it" { node "link" id="info-link" description="Links to itself, and to sources describing it" {
value description="A URL that the link points to" { value description="A URL that the link points to" {
@ -79,7 +90,7 @@ document {
type "string" type "string"
enum "self" "documentation" 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" { node "license" description="The license(s) that the schema is licensed under" {
value description="Name of the used license" { value description="Name of the used license" {
@ -91,7 +102,7 @@ document {
type "string" type "string"
} }
children { children {
node ref="#info-link" node ref=r#"[id="info-link"]"#
} }
} }
node "published" description="When the schema was published" { node "published" description="When the schema was published" {
@ -113,7 +124,7 @@ document {
min 1 min 1
max 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" { node "version" description="The version number of this version of the schema" {
value description="Semver version number" { 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." { 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." { 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" type "string"
@ -138,10 +170,11 @@ document {
} }
prop "ref" description="A globally unique reference to another node." { prop "ref" description="A globally unique reference to another node." {
type "string" type "string"
format "kdl-query"
} }
children { children {
node "prop-names" description="Validations to apply specifically to arbitrary property names" { 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'." { node "other-props-allowed" description="Whether to allow properties other than the ones explicitly listed. Defaults to 'false'." {
max 1 max 1
@ -167,6 +200,7 @@ document {
type "number" type "number"
} }
} }
node ref=r#"[id="value-tag-node"]"#
node "prop" id="prop-node" description="A node property key/value pair." { node "prop" id="prop-node" description="A node property key/value pair." {
value description="The property key." { value description="The property key." {
type "string" type "string"
@ -176,6 +210,7 @@ document {
} }
prop "ref" description="A globally unique reference to another property node." { prop "ref" description="A globally unique reference to another property node." {
type "string" type "string"
format "kdl-query"
} }
prop "description" description="A description of this property's purpose." { prop "description" description="A description of this property's purpose." {
type "string" type "string"
@ -191,6 +226,10 @@ document {
} }
} }
children id="validations" description="General value validations." { 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." { node "type" description="The type for this prop's value." {
max 1 max 1
value { value {
@ -230,7 +269,7 @@ document {
min 1 min 1
type "string" type "string"
// https://json-schema.org/understanding-json-schema/reference/string.html#format // 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)" { 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." { prop "ref" description="A globally unique reference to another value node." {
type "string" type "string"
format "kdl-query"
} }
prop "description" description="A description of this property's purpose." { prop "description" description="A description of this property's purpose." {
type "string" type "string"
} }
children ref="#validations" children ref=r#"[id="validations"]"#
children description="Node value-specific validations" { children description="Node value-specific validations" {
node "min" description="minimum number of values for this node." { node "min" description="minimum number of values for this node." {
max 1 max 1
@ -310,20 +350,22 @@ document {
} }
prop "ref" description="A globally unique reference to another children node." { prop "ref" description="A globally unique reference to another children node." {
type "string" type "string"
format "kdl-query"
} }
prop "description" description="A description of this these children's purpose." { prop "description" description="A description of this these children's purpose." {
type "string" 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" { node "definitions" description="Definitions to reference in parts of the top-level nodes" {
children { children {
node ref="#node-node" node ref=r#"[id="node-node"]"#
node ref="#value-node" node ref=r#"[id="value-node"]"#
node ref="#prop-node" node ref=r#"[id="prop-node"]"#
node ref="#children-node" node ref=r#"[id="children-node"]"#
node ref=r#"[id="tag-node"]"#
} }
} }
} }