From d83c0b674703ee15e4af7675cfba8e935e0e9599 Mon Sep 17 00:00:00 2001 From: Ralf Handl Date: Mon, 27 Sep 2021 17:45:40 +0200 Subject: [PATCH 01/31] Function "query" --- vocabularies/Org.OData.JSON.V1.json | 31 +++++++++++++++ vocabularies/Org.OData.JSON.V1.md | 57 +++++++++++++++++++++++++++- vocabularies/Org.OData.JSON.V1.xml | 58 +++++++++++++++++++++++++++++ 3 files changed, 145 insertions(+), 1 deletion(-) diff --git a/vocabularies/Org.OData.JSON.V1.json b/vocabularies/Org.OData.JSON.V1.json index f08652a6..e7920a89 100644 --- a/vocabularies/Org.OData.JSON.V1.json +++ b/vocabularies/Org.OData.JSON.V1.json @@ -41,6 +41,31 @@ "@Core.Description": "The JSON Schema for JSON values of the annotated property, parameter, return type, term, or type definition", "@Core.LongDescription": "The schema can be a schema reference, i.e. `{\"$ref\":\"url/of/schemafile#/path/to/schema/within/schemafile\"}`" }, + "query": [ + { + "$Kind": "Function", + "@Core.Description": "Query stream values of media type `application/json`", + "@Core.LongDescription": "Extracts a JSON value, such as an array or object, or a JSON scalar value, such as a string, number, or boolean.\n\n_TODO: describe behavior and edge cases, especially null handling_\n ", + "$Parameter": [ + { + "$Name": "input", + "$Type": "JSON.JSON", + "$Nullable": true, + "@Core.Description": "JSON input" + }, + { + "$Name": "path", + "$Type": "JSON.Path", + "@Core.Description": "JSONPath expression to be applied to value of `expr`" + } + ], + "$ReturnType": { + "$Type": "JSON.JSON", + "$Nullable": true, + "@Core.Description": "JSON value resulting from applying `path` to `input`" + } + } + ], "JSON": { "$Kind": "TypeDefinition", "$UnderlyingType": "Edm.Stream", @@ -49,6 +74,12 @@ "@Core.AcceptableMediaTypes": [ "application/json" ] + }, + "Path": { + "$Kind": "TypeDefinition", + "$UnderlyingType": "Edm.String", + "@Core.Description": "[JSONPath](https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-01) expression", + "@Core.LongDescription": "Implementations SHOULD support at least the following subset of JSONPath:\n\n_TODO: check which data sources support which subset, then reduce expressions_\n- SQL Server: https://docs.microsoft.com/en-us/sql/relational-databases/json/json-path-expressions-sql-server?view=sql-server-2017\n- SAP HANA: https://help.sap.com/products/SAP_HANA_PLATFORM/4fe29514fd584807ac9f2a04f6754767/3126ea33d50d42d19517a08fe22ec5a1.html?version=2.0.05#description\n- Google BigQuery references the Java implementation - all of it supported?\n\nJSONPath | Description | Examples\n---------|-------------|--------\n`$` | The root object, array, or value\n`.` | Child member operator | `$.foo`, `$.foo.bar`\n`..` | Recursive descendant operator: searches for the specified member name recursively and returns an array of all values with this property name | `$..foo`\n`*` | Wildcard matching all elements in an object or array | `$.foo.*`, `$.bar[*]`\n`[]` | Subscript operator, accepting names (single-quoted strings) or array indices (zero-based integers, negative integers count from the end of the array) | `$['foo']`, `$.foo['bar']`, `$.bar[0]`, `$.bar[-1]`\n`[,]` | Union operator for alternate names or array indices as a set | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]`\n`[start:end]` | Array subset by range of indices | `$.bar[2:4]`\n`[start:]` | Array subset from index to end of array | `$.bar[2:]`\n`[:end]` | Array subset from start of array to index | `$.bar[:4]`\n`[-start:]` | Array subset from _length-start_ to end of array | `$.bar[-3:]`\n`[?()]` | Filter expession | `$.bar[?(@.baz==42)]`\n`[()]` | Static expression | `$.bar[(@.length-1)]`\n`@` | in filter expressions: the current node being processed\n\n**References**\n- Current IETF draft: https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-01\n- Historic site: https://goessner.net/articles/JsonPath/\n- Node.js implementation: https://www.npmjs.com/package/jsonpath\n- Java implementation: https://github.com/json-path/JsonPath\n- Online evaluator: https://jsonpath.com/\n " } } } \ No newline at end of file diff --git a/vocabularies/Org.OData.JSON.V1.md b/vocabularies/Org.OData.JSON.V1.md index b87119b8..a8d366b7 100644 --- a/vocabularies/Org.OData.JSON.V1.md +++ b/vocabularies/Org.OData.JSON.V1.md @@ -10,7 +10,62 @@ Term|Type|Description :---|:---|:---------- [Schema](./Org.OData.JSON.V1.xml#L67:~:text=The JSON Schema for JSON values of the annotated property, parameter, return type, term, or type definition
The schema can be a schema reference, i.e. `{"$ref":"url/of/schemafile#/path/to/schema/within/schemafile"}` -## [JSON](./Org.OData.JSON.V1.xml#L75:~:text=[query](./Org.OData.JSON.V1.xml#L75:~:text=[JSON](./Org.OData.JSON.V1.xml#L96:~:text=[Path](./Org.OData.JSON.V1.xml#L107:~:text= + + + + Extracts a JSON value, such as an array or object, or a JSON scalar value, such as a string, number, or boolean. + +_TODO: describe behavior and edge cases, especially null handling_ + + + + + + + + + + + + + + + @@ -82,6 +103,43 @@ + + + + + Implementations SHOULD support at least the following subset of JSONPath: + +_TODO: check which data sources support which subset, then reduce expressions_ +- SQL Server: https://docs.microsoft.com/en-us/sql/relational-databases/json/json-path-expressions-sql-server?view=sql-server-2017 +- SAP HANA: https://help.sap.com/products/SAP_HANA_PLATFORM/4fe29514fd584807ac9f2a04f6754767/3126ea33d50d42d19517a08fe22ec5a1.html?version=2.0.05#description +- Google BigQuery references the Java implementation - all of it supported? + +JSONPath | Description | Examples +---------|-------------|-------- +`$` | The root object, array, or value +`.` | Child member operator | `$.foo`, `$.foo.bar` +`..` | Recursive descendant operator: searches for the specified member name recursively and returns an array of all values with this property name | `$..foo` +`*` | Wildcard matching all elements in an object or array | `$.foo.*`, `$.bar[*]` +`[]` | Subscript operator, accepting names (single-quoted strings) or array indices (zero-based integers, negative integers count from the end of the array) | `$['foo']`, `$.foo['bar']`, `$.bar[0]`, `$.bar[-1]` +`[,]` | Union operator for alternate names or array indices as a set | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]` +`[start:end]` | Array subset by range of indices | `$.bar[2:4]` +`[start:]` | Array subset from index to end of array | `$.bar[2:]` +`[:end]` | Array subset from start of array to index | `$.bar[:4]` +`[-start:]` | Array subset from _length-start_ to end of array | `$.bar[-3:]` +`[?()]` | Filter expession | `$.bar[?(@.baz==42)]` +`[()]` | Static expression | `$.bar[(@.length-1)]` +`@` | in filter expressions: the current node being processed + +**References** +- Current IETF draft: https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-01 +- Historic site: https://goessner.net/articles/JsonPath/ +- Node.js implementation: https://www.npmjs.com/package/jsonpath +- Java implementation: https://github.com/json-path/JsonPath +- Online evaluator: https://jsonpath.com/ + + + + From 1641c4986f3b0c21d644a26c60000daee26592a0 Mon Sep 17 00:00:00 2001 From: Ralf Handl Date: Tue, 28 Sep 2021 15:14:42 +0200 Subject: [PATCH 02/31] Added "value" function, defined processing rules --- vocabularies/Org.OData.JSON.V1.json | 31 ++++++++++++++++++++-- vocabularies/Org.OData.JSON.V1.md | 41 +++++++++++++++++++++++------ vocabularies/Org.OData.JSON.V1.xml | 38 +++++++++++++++++++++----- 3 files changed, 94 insertions(+), 16 deletions(-) diff --git a/vocabularies/Org.OData.JSON.V1.json b/vocabularies/Org.OData.JSON.V1.json index e7920a89..21597844 100644 --- a/vocabularies/Org.OData.JSON.V1.json +++ b/vocabularies/Org.OData.JSON.V1.json @@ -44,8 +44,8 @@ "query": [ { "$Kind": "Function", - "@Core.Description": "Query stream values of media type `application/json`", - "@Core.LongDescription": "Extracts a JSON value, such as an array or object, or a JSON scalar value, such as a string, number, or boolean.\n\n_TODO: describe behavior and edge cases, especially null handling_\n ", + "@Core.Description": "Query stream values of media type `application/json`, returning a stream value of media type `application/json`", + "@Core.LongDescription": "Extracts a JSON value, such as an array, object, or a JSON scalar value (string, number, boolean, or `null`) from the `input` JSON value:\n- If `path` only consists of child member and single subscript operators, it returns the identified single node within `input`, or `null` if no node is identified. \n- If `path` potentially identifies multiple nodes within `input` (by using recursive descendant, wildcard, array subset, or array filter expressions), it returns an array containing the identified nodes, or an empty array if no node is identified. \n- If `input` is not a valid JSON value, the function returns `null`.\n- If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input`, the function returns `null`. \n ", "$Parameter": [ { "$Name": "input", @@ -56,6 +56,7 @@ { "$Name": "path", "$Type": "JSON.Path", + "$Nullable": true, "@Core.Description": "JSONPath expression to be applied to value of `expr`" } ], @@ -66,6 +67,32 @@ } } ], + "value": [ + { + "$Kind": "Function", + "@Core.Description": "Query stream values of media type `application/json`, returning an OData primitive value", + "@Core.LongDescription": "Extracts an OData primitive value from the `input` JSON value:\n- If `path` only consists of child member and single subscript operators and identifies a single scalar JSON value (string, number, boolean, or `null`) within `input`, it returns the identified single value cast to an OData primitive value (see below).\n- If `path` identifies multiple nodes within `input` (by using recursive descendant, wildcard, array subset, or array filter expressions), identifies an object or array, or does not identify any node, the function returns `null`.\n- If `input` is not a valid JSON value, the function returns `null`.\n- If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input`, the function returns `null`.\n\nIf a single non-null scalar JSON value is identified by `path` within `input`, the function returns that value as a primitive value of type\n- `Edm.String` if the value is a JSON string\n- `Edm.Boolean` if the value is `true` or `false`\n- `Edm.Decimal` with unspecified precision and floating scale if the value is a JSON number\n ", + "$Parameter": [ + { + "$Name": "input", + "$Type": "JSON.JSON", + "$Nullable": true, + "@Core.Description": "JSON input" + }, + { + "$Name": "path", + "$Type": "JSON.Path", + "$Nullable": true, + "@Core.Description": "JSONPath expression to be applied to value of `expr`" + } + ], + "$ReturnType": { + "$Type": "Edm.PrimitiveType", + "$Nullable": true, + "@Core.Description": "OData primitive value resulting from applying `path` to `input`" + } + } + ], "JSON": { "$Kind": "TypeDefinition", "$UnderlyingType": "Edm.Stream", diff --git a/vocabularies/Org.OData.JSON.V1.md b/vocabularies/Org.OData.JSON.V1.md index a8d366b7..5d16fa55 100644 --- a/vocabularies/Org.OData.JSON.V1.md +++ b/vocabularies/Org.OData.JSON.V1.md @@ -15,26 +15,51 @@ Term|Type|Description ### [query](./Org.OData.JSON.V1.xml#L75:~:text=[value](./Org.OData.JSON.V1.xml#L96:~:text=[JSON](./Org.OData.JSON.V1.xml#L96:~:text=[JSON](./Org.OData.JSON.V1.xml#L122:~:text=[Path](./Org.OData.JSON.V1.xml#L107:~:text=[Path](./Org.OData.JSON.V1.xml#L133:~:text= - + - Extracts a JSON value, such as an array or object, or a JSON scalar value, such as a string, number, or boolean. - -_TODO: describe behavior and edge cases, especially null handling_ + Extracts a JSON value, such as an array, object, or a JSON scalar value (string, number, boolean, or `null`) from the `input` JSON value: +- If `path` only consists of child member and single subscript operators, it returns the identified single node within `input`, or `null` if no node is identified. +- If `path` potentially identifies multiple nodes within `input` (by using recursive descendant, wildcard, array subset, or array filter expressions), it returns an array containing the identified nodes, or an empty array if no node is identified. +- If `input` is not a valid JSON value, the function returns `null`. +- If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input`, the function returns `null`. - + @@ -91,7 +93,31 @@ _TODO: describe behavior and edge cases, especially null handling_ - + + + + Extracts an OData primitive value from the `input` JSON value: +- If `path` only consists of child member and single subscript operators and identifies a single scalar JSON value (string, number, boolean, or `null`) within `input`, it returns the identified single value cast to an OData primitive value (see below). +- If `path` identifies multiple nodes within `input` (by using recursive descendant, wildcard, array subset, or array filter expressions), identifies an object or array, or does not identify any node, the function returns `null`. +- If `input` is not a valid JSON value, the function returns `null`. +- If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input`, the function returns `null`. + +If a single non-null scalar JSON value is identified by `path` within `input`, the function returns that value as a primitive value of type +- `Edm.String` if the value is a JSON string +- `Edm.Boolean` if the value is `true` or `false` +- `Edm.Decimal` with unspecified precision and floating scale if the value is a JSON number + + + + + + + + + + + + From b41aad8e884689e2b9ec8dad877a36dba72d2890 Mon Sep 17 00:00:00 2001 From: Ralf Handl Date: Wed, 29 Sep 2021 13:28:47 +0200 Subject: [PATCH 03/31] Recommended and optional expressions --- vocabularies/Org.OData.JSON.V1.json | 2 +- vocabularies/Org.OData.JSON.V1.md | 36 +++++++++++++++-------------- vocabularies/Org.OData.JSON.V1.xml | 36 +++++++++++++++-------------- 3 files changed, 39 insertions(+), 35 deletions(-) diff --git a/vocabularies/Org.OData.JSON.V1.json b/vocabularies/Org.OData.JSON.V1.json index 21597844..0217533e 100644 --- a/vocabularies/Org.OData.JSON.V1.json +++ b/vocabularies/Org.OData.JSON.V1.json @@ -106,7 +106,7 @@ "$Kind": "TypeDefinition", "$UnderlyingType": "Edm.String", "@Core.Description": "[JSONPath](https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-01) expression", - "@Core.LongDescription": "Implementations SHOULD support at least the following subset of JSONPath:\n\n_TODO: check which data sources support which subset, then reduce expressions_\n- SQL Server: https://docs.microsoft.com/en-us/sql/relational-databases/json/json-path-expressions-sql-server?view=sql-server-2017\n- SAP HANA: https://help.sap.com/products/SAP_HANA_PLATFORM/4fe29514fd584807ac9f2a04f6754767/3126ea33d50d42d19517a08fe22ec5a1.html?version=2.0.05#description\n- Google BigQuery references the Java implementation - all of it supported?\n\nJSONPath | Description | Examples\n---------|-------------|--------\n`$` | The root object, array, or value\n`.` | Child member operator | `$.foo`, `$.foo.bar`\n`..` | Recursive descendant operator: searches for the specified member name recursively and returns an array of all values with this property name | `$..foo`\n`*` | Wildcard matching all elements in an object or array | `$.foo.*`, `$.bar[*]`\n`[]` | Subscript operator, accepting names (single-quoted strings) or array indices (zero-based integers, negative integers count from the end of the array) | `$['foo']`, `$.foo['bar']`, `$.bar[0]`, `$.bar[-1]`\n`[,]` | Union operator for alternate names or array indices as a set | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]`\n`[start:end]` | Array subset by range of indices | `$.bar[2:4]`\n`[start:]` | Array subset from index to end of array | `$.bar[2:]`\n`[:end]` | Array subset from start of array to index | `$.bar[:4]`\n`[-start:]` | Array subset from _length-start_ to end of array | `$.bar[-3:]`\n`[?()]` | Filter expession | `$.bar[?(@.baz==42)]`\n`[()]` | Static expression | `$.bar[(@.length-1)]`\n`@` | in filter expressions: the current node being processed\n\n**References**\n- Current IETF draft: https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-01\n- Historic site: https://goessner.net/articles/JsonPath/\n- Node.js implementation: https://www.npmjs.com/package/jsonpath\n- Java implementation: https://github.com/json-path/JsonPath\n- Online evaluator: https://jsonpath.com/\n " + "@Core.LongDescription": "Implementations SHOULD support at least the following subset of JSONPath:\n\nJSONPath | Description | Examples\n---------|-------------|--------\n`$` | Root selector | `$`\n`.` | Member selector | `$.foo`, `$.foo.bar`\n`[]` | Index selector, accepting member names (single- or double-quoted strings using JSON escaping rules) or zero-based array indices (non-negative base-10 integers) | `$['foo']`, `$.foo[\"bar\"]`, `$.bar[0]`, `$.bar[42]`\n\nImplementations MAY support in addition:\n\nJSONPath | Description | Examples\n---------|-------------|--------\n`[]` | Subscript selector with negative integer array indices (count from the end of the array) | `$.bar[-1]`\n`..` | Descendant selector: searches for the specified member name recursively and returns an array of all values with this member name | `$..foo`\n`*` | Wildcard selector matching all elements in an object or array | `$.foo.*`, `$.bar[*]`, `$..*`\n`[,]` | Union selector for alternate names or array indices as a set | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]`\n`[start:end]` | Array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:4]`\n`[start:]` | Array subset from _start_ to end of array | `$.bar[2:]`\n`[:n]` | The first _n_ array items | `$.bar[:4]`\n`[-n:]` | The last _n_ array items | `$.bar[-3:]`\n`[start:end:step]` | [Array slice selector](https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-01#section-3.5.6) |\n`[?()]` | Filter selector | `$.bar[?(@.baz==42)]`\n`()` | Static expression | `$.bar[(@.length-1)]`\n`@` | in expressions: the current node being processed\n\n**References**\n- Current IETF draft: https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-01\n- Historic site: https://goessner.net/articles/JsonPath/\n- Node.js implementation: https://www.npmjs.com/package/jsonpath\n- Java implementation: https://github.com/json-path/JsonPath\n- Online evaluator: https://jsonpath.com/\n " } } } \ No newline at end of file diff --git a/vocabularies/Org.OData.JSON.V1.md b/vocabularies/Org.OData.JSON.V1.md index 5d16fa55..f31aa4ec 100644 --- a/vocabularies/Org.OData.JSON.V1.md +++ b/vocabularies/Org.OData.JSON.V1.md @@ -66,26 +66,28 @@ Textual data of media type `application/json` Implementations SHOULD support at least the following subset of JSONPath: -_TODO: check which data sources support which subset, then reduce expressions_ -- SQL Server: https://docs.microsoft.com/en-us/sql/relational-databases/json/json-path-expressions-sql-server?view=sql-server-2017 -- SAP HANA: https://help.sap.com/products/SAP_HANA_PLATFORM/4fe29514fd584807ac9f2a04f6754767/3126ea33d50d42d19517a08fe22ec5a1.html?version=2.0.05#description -- Google BigQuery references the Java implementation - all of it supported? +JSONPath | Description | Examples +---------|-------------|-------- +`$` | Root selector | `$` +`.` | Member selector | `$.foo`, `$.foo.bar` +`[]` | Index selector, accepting member names (single- or double-quoted strings using JSON escaping rules) or zero-based array indices (non-negative base-10 integers) | `$['foo']`, `$.foo["bar"]`, `$.bar[0]`, `$.bar[42]` + +Implementations MAY support in addition: JSONPath | Description | Examples ---------|-------------|-------- -`$` | The root object, array, or value -`.` | Child member operator | `$.foo`, `$.foo.bar` -`..` | Recursive descendant operator: searches for the specified member name recursively and returns an array of all values with this property name | `$..foo` -`*` | Wildcard matching all elements in an object or array | `$.foo.*`, `$.bar[*]` -`[]` | Subscript operator, accepting names (single-quoted strings) or array indices (zero-based integers, negative integers count from the end of the array) | `$['foo']`, `$.foo['bar']`, `$.bar[0]`, `$.bar[-1]` -`[,]` | Union operator for alternate names or array indices as a set | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]` -`[start:end]` | Array subset by range of indices | `$.bar[2:4]` -`[start:]` | Array subset from index to end of array | `$.bar[2:]` -`[:end]` | Array subset from start of array to index | `$.bar[:4]` -`[-start:]` | Array subset from _length-start_ to end of array | `$.bar[-3:]` -`[?()]` | Filter expession | `$.bar[?(@.baz==42)]` -`[()]` | Static expression | `$.bar[(@.length-1)]` -`@` | in filter expressions: the current node being processed +`[]` | Subscript selector with negative integer array indices (count from the end of the array) | `$.bar[-1]` +`..` | Descendant selector: searches for the specified member name recursively and returns an array of all values with this member name | `$..foo` +`*` | Wildcard selector matching all elements in an object or array | `$.foo.*`, `$.bar[*]`, `$..*` +`[,]` | Union selector for alternate names or array indices as a set | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]` +`[start:end]` | Array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:4]` +`[start:]` | Array subset from _start_ to end of array | `$.bar[2:]` +`[:n]` | The first _n_ array items | `$.bar[:4]` +`[-n:]` | The last _n_ array items | `$.bar[-3:]` +`[start:end:step]` | [Array slice selector](https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-01#section-3.5.6) | +`[?()]` | Filter selector | `$.bar[?(@.baz==42)]` +`()` | Static expression | `$.bar[(@.length-1)]` +`@` | in expressions: the current node being processed **References** - Current IETF draft: https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-01 diff --git a/vocabularies/Org.OData.JSON.V1.xml b/vocabularies/Org.OData.JSON.V1.xml index 9c3084de..179ac956 100644 --- a/vocabularies/Org.OData.JSON.V1.xml +++ b/vocabularies/Org.OData.JSON.V1.xml @@ -135,26 +135,28 @@ If a single non-null scalar JSON value is identified by `path` within `input`, t Implementations SHOULD support at least the following subset of JSONPath: -_TODO: check which data sources support which subset, then reduce expressions_ -- SQL Server: https://docs.microsoft.com/en-us/sql/relational-databases/json/json-path-expressions-sql-server?view=sql-server-2017 -- SAP HANA: https://help.sap.com/products/SAP_HANA_PLATFORM/4fe29514fd584807ac9f2a04f6754767/3126ea33d50d42d19517a08fe22ec5a1.html?version=2.0.05#description -- Google BigQuery references the Java implementation - all of it supported? +JSONPath | Description | Examples +---------|-------------|-------- +`$` | Root selector | `$` +`.` | Member selector | `$.foo`, `$.foo.bar` +`[]` | Index selector, accepting member names (single- or double-quoted strings using JSON escaping rules) or zero-based array indices (non-negative base-10 integers) | `$['foo']`, `$.foo["bar"]`, `$.bar[0]`, `$.bar[42]` + +Implementations MAY support in addition: JSONPath | Description | Examples ---------|-------------|-------- -`$` | The root object, array, or value -`.` | Child member operator | `$.foo`, `$.foo.bar` -`..` | Recursive descendant operator: searches for the specified member name recursively and returns an array of all values with this property name | `$..foo` -`*` | Wildcard matching all elements in an object or array | `$.foo.*`, `$.bar[*]` -`[]` | Subscript operator, accepting names (single-quoted strings) or array indices (zero-based integers, negative integers count from the end of the array) | `$['foo']`, `$.foo['bar']`, `$.bar[0]`, `$.bar[-1]` -`[,]` | Union operator for alternate names or array indices as a set | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]` -`[start:end]` | Array subset by range of indices | `$.bar[2:4]` -`[start:]` | Array subset from index to end of array | `$.bar[2:]` -`[:end]` | Array subset from start of array to index | `$.bar[:4]` -`[-start:]` | Array subset from _length-start_ to end of array | `$.bar[-3:]` -`[?()]` | Filter expession | `$.bar[?(@.baz==42)]` -`[()]` | Static expression | `$.bar[(@.length-1)]` -`@` | in filter expressions: the current node being processed +`[]` | Subscript selector with negative integer array indices (count from the end of the array) | `$.bar[-1]` +`..` | Descendant selector: searches for the specified member name recursively and returns an array of all values with this member name | `$..foo` +`*` | Wildcard selector matching all elements in an object or array | `$.foo.*`, `$.bar[*]`, `$..*` +`[,]` | Union selector for alternate names or array indices as a set | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]` +`[start:end]` | Array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:4]` +`[start:]` | Array subset from _start_ to end of array | `$.bar[2:]` +`[:n]` | The first _n_ array items | `$.bar[:4]` +`[-n:]` | The last _n_ array items | `$.bar[-3:]` +`[start:end:step]` | [Array slice selector](https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-01#section-3.5.6) | +`[?()]` | Filter selector | `$.bar[?(@.baz==42)]` +`()` | Static expression | `$.bar[(@.length-1)]` +`@` | in expressions: the current node being processed **References** - Current IETF draft: https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-01 From 5f153de1776070c6ca56f95b7268e4f0faa29d49 Mon Sep 17 00:00:00 2001 From: Ralf Handl Date: Wed, 29 Sep 2021 15:06:01 +0200 Subject: [PATCH 04/31] Aligned terminology with draft RFC --- vocabularies/Org.OData.JSON.V1.json | 6 +++--- vocabularies/Org.OData.JSON.V1.md | 24 ++++++++++++------------ vocabularies/Org.OData.JSON.V1.xml | 24 ++++++++++++------------ 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/vocabularies/Org.OData.JSON.V1.json b/vocabularies/Org.OData.JSON.V1.json index 0217533e..b8f6fca1 100644 --- a/vocabularies/Org.OData.JSON.V1.json +++ b/vocabularies/Org.OData.JSON.V1.json @@ -45,7 +45,7 @@ { "$Kind": "Function", "@Core.Description": "Query stream values of media type `application/json`, returning a stream value of media type `application/json`", - "@Core.LongDescription": "Extracts a JSON value, such as an array, object, or a JSON scalar value (string, number, boolean, or `null`) from the `input` JSON value:\n- If `path` only consists of child member and single subscript operators, it returns the identified single node within `input`, or `null` if no node is identified. \n- If `path` potentially identifies multiple nodes within `input` (by using recursive descendant, wildcard, array subset, or array filter expressions), it returns an array containing the identified nodes, or an empty array if no node is identified. \n- If `input` is not a valid JSON value, the function returns `null`.\n- If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input`, the function returns `null`. \n ", + "@Core.LongDescription": "Extracts a JSON value, such as an array, object, or a JSON scalar value (string, number, boolean, or `null`) from the `input` JSON value:\n- If `path` only consists of the root selector followed by member and index selectors, it returns the identified single node within `input`, or `null` if no node is identified. \n- If `path` potentially identifies multiple nodes within `input` (by using descendant, wildcard, union, array subset, or filter selectors), it returns an array containing the identified nodes, or an empty array if no node is identified. \n- If `input` is not a valid JSON value, the function returns `null`.\n- If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input` (for example applying an index selector to a scalar value), the function returns `null`. \n ", "$Parameter": [ { "$Name": "input", @@ -71,7 +71,7 @@ { "$Kind": "Function", "@Core.Description": "Query stream values of media type `application/json`, returning an OData primitive value", - "@Core.LongDescription": "Extracts an OData primitive value from the `input` JSON value:\n- If `path` only consists of child member and single subscript operators and identifies a single scalar JSON value (string, number, boolean, or `null`) within `input`, it returns the identified single value cast to an OData primitive value (see below).\n- If `path` identifies multiple nodes within `input` (by using recursive descendant, wildcard, array subset, or array filter expressions), identifies an object or array, or does not identify any node, the function returns `null`.\n- If `input` is not a valid JSON value, the function returns `null`.\n- If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input`, the function returns `null`.\n\nIf a single non-null scalar JSON value is identified by `path` within `input`, the function returns that value as a primitive value of type\n- `Edm.String` if the value is a JSON string\n- `Edm.Boolean` if the value is `true` or `false`\n- `Edm.Decimal` with unspecified precision and floating scale if the value is a JSON number\n ", + "@Core.LongDescription": "Extracts a single OData primitive value from the `input` JSON value:\n- If `path` only consists of the root selector followed by member and index selectors and identifies a single scalar JSON value (string, number, boolean, or `null`) within `input`, it returns the identified single value cast to an OData primitive value (see below).\n- If `path` identifies multiple nodes within `input` (by using descendant, wildcard, union, array subset, or filter selectors), identifies an object or array, or does not identify any node, the function returns `null`.\n- If `input` is not a valid JSON value, the function returns `null`.\n- If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input` (for example applying an index selector to a scalar value), the function returns `null`.\n\nIf a single non-null scalar JSON value is identified by `path` within `input`, the function returns that value as an OData primitive value of type\n- `Edm.String` if the value is a JSON string\n- `Edm.Boolean` if the value is `true` or `false`\n- `Edm.Decimal` with unspecified precision and floating scale if the value is a JSON number\n ", "$Parameter": [ { "$Name": "input", @@ -106,7 +106,7 @@ "$Kind": "TypeDefinition", "$UnderlyingType": "Edm.String", "@Core.Description": "[JSONPath](https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-01) expression", - "@Core.LongDescription": "Implementations SHOULD support at least the following subset of JSONPath:\n\nJSONPath | Description | Examples\n---------|-------------|--------\n`$` | Root selector | `$`\n`.` | Member selector | `$.foo`, `$.foo.bar`\n`[]` | Index selector, accepting member names (single- or double-quoted strings using JSON escaping rules) or zero-based array indices (non-negative base-10 integers) | `$['foo']`, `$.foo[\"bar\"]`, `$.bar[0]`, `$.bar[42]`\n\nImplementations MAY support in addition:\n\nJSONPath | Description | Examples\n---------|-------------|--------\n`[]` | Subscript selector with negative integer array indices (count from the end of the array) | `$.bar[-1]`\n`..` | Descendant selector: searches for the specified member name recursively and returns an array of all values with this member name | `$..foo`\n`*` | Wildcard selector matching all elements in an object or array | `$.foo.*`, `$.bar[*]`, `$..*`\n`[,]` | Union selector for alternate names or array indices as a set | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]`\n`[start:end]` | Array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:4]`\n`[start:]` | Array subset from _start_ to end of array | `$.bar[2:]`\n`[:n]` | The first _n_ array items | `$.bar[:4]`\n`[-n:]` | The last _n_ array items | `$.bar[-3:]`\n`[start:end:step]` | [Array slice selector](https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-01#section-3.5.6) |\n`[?()]` | Filter selector | `$.bar[?(@.baz==42)]`\n`()` | Static expression | `$.bar[(@.length-1)]`\n`@` | in expressions: the current node being processed\n\n**References**\n- Current IETF draft: https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-01\n- Historic site: https://goessner.net/articles/JsonPath/\n- Node.js implementation: https://www.npmjs.com/package/jsonpath\n- Java implementation: https://github.com/json-path/JsonPath\n- Online evaluator: https://jsonpath.com/\n " + "@Core.LongDescription": "Implementations SHOULD support at least the following subset of JSONPath:\n\nJSONPath | Description | Examples\n---------|-------------|--------\n`$` | Root selector | `$`\n`.` | Member selector | `$.foo`, `$.foo.bar`\n`[]` | Index selector with member name (single- or double-quoted string using JSON escaping rules) or zero-based array index (non-negative base-10 integer) | `$['foo']`, `$.foo[\"bar\"]`, `$.bar[0]`, `$.bar[42]`\n\nImplementations MAY support in addition:\n\nJSONPath | Description | Examples\n---------|-------------|--------\n`[]` | Index selector with negative integer array index (counts from the end of the array) | `$.bar[-1]`\n`..` | Descendant selector: searches for the specified member name recursively and returns an array of all values with this member name | `$..foo`\n`*` | Wildcard selector matching all elements in an object or array | `$.foo.*`, `$.bar[*]`, `$..*`\n`[,]` | Union selector for alternate member names or array indices as a set | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]`\n`[start:end]` | Array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:5]`, same as `$.bar[2,3,4]`\n`[start:]` | Array subset from _start_ to end of array | `$.bar[2:]`\n`[:n]` | The first _n_ array items | `$.bar[:4]`\n`[-n:]` | The last _n_ array items | `$.bar[-3:]`\n`[start:end:step]` | [Array slice selector](https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-01#section-3.5.6) |\n`[?()]` | Filter selector | `$.bar[?(@.baz==42)]`\n`()` | Static expression | `$.bar[(@.length-1)]`\n`@` | in expressions: the current node being processed\n\n**References**\n- Current IETF draft: https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-01\n- Historic site: https://goessner.net/articles/JsonPath/\n- Node.js implementation: https://www.npmjs.com/package/jsonpath\n- Java implementation: https://github.com/json-path/JsonPath\n- Online evaluator: https://jsonpath.com/\n " } } } \ No newline at end of file diff --git a/vocabularies/Org.OData.JSON.V1.md b/vocabularies/Org.OData.JSON.V1.md index f31aa4ec..5f70e9ff 100644 --- a/vocabularies/Org.OData.JSON.V1.md +++ b/vocabularies/Org.OData.JSON.V1.md @@ -18,10 +18,10 @@ Term|Type|Description Query stream values of media type `application/json`, returning a stream value of media type `application/json` Extracts a JSON value, such as an array, object, or a JSON scalar value (string, number, boolean, or `null`) from the `input` JSON value: -- If `path` only consists of child member and single subscript operators, it returns the identified single node within `input`, or `null` if no node is identified. -- If `path` potentially identifies multiple nodes within `input` (by using recursive descendant, wildcard, array subset, or array filter expressions), it returns an array containing the identified nodes, or an empty array if no node is identified. +- If `path` only consists of the root selector followed by member and index selectors, it returns the identified single node within `input`, or `null` if no node is identified. +- If `path` potentially identifies multiple nodes within `input` (by using descendant, wildcard, union, array subset, or filter selectors), it returns an array containing the identified nodes, or an empty array if no node is identified. - If `input` is not a valid JSON value, the function returns `null`. -- If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input`, the function returns `null`. +- If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input` (for example applying an index selector to a scalar value), the function returns `null`. Parameter|Type|Description @@ -35,13 +35,13 @@ Parameter|Type|Description Query stream values of media type `application/json`, returning an OData primitive value -Extracts an OData primitive value from the `input` JSON value: -- If `path` only consists of child member and single subscript operators and identifies a single scalar JSON value (string, number, boolean, or `null`) within `input`, it returns the identified single value cast to an OData primitive value (see below). -- If `path` identifies multiple nodes within `input` (by using recursive descendant, wildcard, array subset, or array filter expressions), identifies an object or array, or does not identify any node, the function returns `null`. +Extracts a single OData primitive value from the `input` JSON value: +- If `path` only consists of the root selector followed by member and index selectors and identifies a single scalar JSON value (string, number, boolean, or `null`) within `input`, it returns the identified single value cast to an OData primitive value (see below). +- If `path` identifies multiple nodes within `input` (by using descendant, wildcard, union, array subset, or filter selectors), identifies an object or array, or does not identify any node, the function returns `null`. - If `input` is not a valid JSON value, the function returns `null`. -- If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input`, the function returns `null`. +- If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input` (for example applying an index selector to a scalar value), the function returns `null`. -If a single non-null scalar JSON value is identified by `path` within `input`, the function returns that value as a primitive value of type +If a single non-null scalar JSON value is identified by `path` within `input`, the function returns that value as an OData primitive value of type - `Edm.String` if the value is a JSON string - `Edm.Boolean` if the value is `true` or `false` - `Edm.Decimal` with unspecified precision and floating scale if the value is a JSON number @@ -70,17 +70,17 @@ JSONPath | Description | Examples ---------|-------------|-------- `$` | Root selector | `$` `.` | Member selector | `$.foo`, `$.foo.bar` -`[]` | Index selector, accepting member names (single- or double-quoted strings using JSON escaping rules) or zero-based array indices (non-negative base-10 integers) | `$['foo']`, `$.foo["bar"]`, `$.bar[0]`, `$.bar[42]` +`[]` | Index selector with member name (single- or double-quoted string using JSON escaping rules) or zero-based array index (non-negative base-10 integer) | `$['foo']`, `$.foo["bar"]`, `$.bar[0]`, `$.bar[42]` Implementations MAY support in addition: JSONPath | Description | Examples ---------|-------------|-------- -`[]` | Subscript selector with negative integer array indices (count from the end of the array) | `$.bar[-1]` +`[]` | Index selector with negative integer array index (counts from the end of the array) | `$.bar[-1]` `..` | Descendant selector: searches for the specified member name recursively and returns an array of all values with this member name | `$..foo` `*` | Wildcard selector matching all elements in an object or array | `$.foo.*`, `$.bar[*]`, `$..*` -`[,]` | Union selector for alternate names or array indices as a set | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]` -`[start:end]` | Array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:4]` +`[,]` | Union selector for alternate member names or array indices as a set | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]` +`[start:end]` | Array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:5]`, same as `$.bar[2,3,4]` `[start:]` | Array subset from _start_ to end of array | `$.bar[2:]` `[:n]` | The first _n_ array items | `$.bar[:4]` `[-n:]` | The last _n_ array items | `$.bar[-3:]` diff --git a/vocabularies/Org.OData.JSON.V1.xml b/vocabularies/Org.OData.JSON.V1.xml index 179ac956..ebee2b09 100644 --- a/vocabularies/Org.OData.JSON.V1.xml +++ b/vocabularies/Org.OData.JSON.V1.xml @@ -76,10 +76,10 @@ Extracts a JSON value, such as an array, object, or a JSON scalar value (string, number, boolean, or `null`) from the `input` JSON value: -- If `path` only consists of child member and single subscript operators, it returns the identified single node within `input`, or `null` if no node is identified. -- If `path` potentially identifies multiple nodes within `input` (by using recursive descendant, wildcard, array subset, or array filter expressions), it returns an array containing the identified nodes, or an empty array if no node is identified. +- If `path` only consists of the root selector followed by member and index selectors, it returns the identified single node within `input`, or `null` if no node is identified. +- If `path` potentially identifies multiple nodes within `input` (by using descendant, wildcard, union, array subset, or filter selectors), it returns an array containing the identified nodes, or an empty array if no node is identified. - If `input` is not a valid JSON value, the function returns `null`. -- If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input`, the function returns `null`. +- If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input` (for example applying an index selector to a scalar value), the function returns `null`. @@ -96,13 +96,13 @@ - Extracts an OData primitive value from the `input` JSON value: -- If `path` only consists of child member and single subscript operators and identifies a single scalar JSON value (string, number, boolean, or `null`) within `input`, it returns the identified single value cast to an OData primitive value (see below). -- If `path` identifies multiple nodes within `input` (by using recursive descendant, wildcard, array subset, or array filter expressions), identifies an object or array, or does not identify any node, the function returns `null`. + Extracts a single OData primitive value from the `input` JSON value: +- If `path` only consists of the root selector followed by member and index selectors and identifies a single scalar JSON value (string, number, boolean, or `null`) within `input`, it returns the identified single value cast to an OData primitive value (see below). +- If `path` identifies multiple nodes within `input` (by using descendant, wildcard, union, array subset, or filter selectors), identifies an object or array, or does not identify any node, the function returns `null`. - If `input` is not a valid JSON value, the function returns `null`. -- If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input`, the function returns `null`. +- If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input` (for example applying an index selector to a scalar value), the function returns `null`. -If a single non-null scalar JSON value is identified by `path` within `input`, the function returns that value as a primitive value of type +If a single non-null scalar JSON value is identified by `path` within `input`, the function returns that value as an OData primitive value of type - `Edm.String` if the value is a JSON string - `Edm.Boolean` if the value is `true` or `false` - `Edm.Decimal` with unspecified precision and floating scale if the value is a JSON number @@ -139,17 +139,17 @@ JSONPath | Description | Examples ---------|-------------|-------- `$` | Root selector | `$` `.` | Member selector | `$.foo`, `$.foo.bar` -`[]` | Index selector, accepting member names (single- or double-quoted strings using JSON escaping rules) or zero-based array indices (non-negative base-10 integers) | `$['foo']`, `$.foo["bar"]`, `$.bar[0]`, `$.bar[42]` +`[]` | Index selector with member name (single- or double-quoted string using JSON escaping rules) or zero-based array index (non-negative base-10 integer) | `$['foo']`, `$.foo["bar"]`, `$.bar[0]`, `$.bar[42]` Implementations MAY support in addition: JSONPath | Description | Examples ---------|-------------|-------- -`[]` | Subscript selector with negative integer array indices (count from the end of the array) | `$.bar[-1]` +`[]` | Index selector with negative integer array index (counts from the end of the array) | `$.bar[-1]` `..` | Descendant selector: searches for the specified member name recursively and returns an array of all values with this member name | `$..foo` `*` | Wildcard selector matching all elements in an object or array | `$.foo.*`, `$.bar[*]`, `$..*` -`[,]` | Union selector for alternate names or array indices as a set | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]` -`[start:end]` | Array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:4]` +`[,]` | Union selector for alternate member names or array indices as a set | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]` +`[start:end]` | Array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:5]`, same as `$.bar[2,3,4]` `[start:]` | Array subset from _start_ to end of array | `$.bar[2:]` `[:n]` | The first _n_ array items | `$.bar[:4]` `[-n:]` | The last _n_ array items | `$.bar[-3:]` From b1e1ea91233c08c74444dd1996179e467c5f3c07 Mon Sep 17 00:00:00 2001 From: Ralf Handl Date: Fri, 1 Oct 2021 10:40:27 +0200 Subject: [PATCH 05/31] Examples --- vocabularies/Org.OData.JSON.V1.json | 3 +- vocabularies/Org.OData.JSON.V1.md | 56 ++++++++++++++++++++++------- vocabularies/Org.OData.JSON.V1.xml | 36 ++++++++++++++++++- 3 files changed, 81 insertions(+), 14 deletions(-) diff --git a/vocabularies/Org.OData.JSON.V1.json b/vocabularies/Org.OData.JSON.V1.json index b8f6fca1..3c24f3db 100644 --- a/vocabularies/Org.OData.JSON.V1.json +++ b/vocabularies/Org.OData.JSON.V1.json @@ -12,7 +12,8 @@ }, "Org.OData.JSON.V1": { "$Alias": "JSON", - "@Core.Description": "Terms for JSON properties", + "@Core.Description": "Terms, types, and functions for JSON properties", + "@Core.LongDescription": "\n\n> Motivation from OData Extension for JSON Data - A Directional White Paper \n\n> Example schema - separate files, link here, show excerpt\n\n**Example**\n\nThe `Employees` entity set has a property `resume` of type `JSON.JSON`, and one of its entities has a `resume` of\n```json\n{ \n \"ssn\": \"1234\", \n \"lastname\": \"Doe\", \n \"address\": {\n \"zipcode\": \"10022\", \n \"street\": \"ABC st\"\n },\n \"experience\": \"excellent\", \n ...\n }\n```\n\nThis allows to\n```http\nGET http://www.example.com/mycompany/Employees\n ?$filter=JSON.value(resume,'$.lastname') eq 'Doe'\n &$orderby=JSON.value(resume,'$.experience')\n &$compute=JSON.query(resume,'$.address') as address\n &$expand=address\n```\n ", "@Core.Links": [ { "rel": "alternate", diff --git a/vocabularies/Org.OData.JSON.V1.md b/vocabularies/Org.OData.JSON.V1.md index 5f70e9ff..74047c8a 100644 --- a/vocabularies/Org.OData.JSON.V1.md +++ b/vocabularies/Org.OData.JSON.V1.md @@ -1,19 +1,51 @@ # JSON Vocabulary **Namespace: [Org.OData.JSON.V1](Org.OData.JSON.V1.xml)** -Terms for JSON properties +Terms, types, and functions for JSON properties + + + +> Motivation from OData Extension for JSON Data - A Directional White Paper + +> Example schema - separate files, link here, show excerpt + +**Example** + +The `Employees` entity set has a property `resume` of type `JSON.JSON`, and one of its entities has a `resume` of +```json +{ + "ssn": "1234", + "lastname": "Doe", + "address": { + "zipcode": "10022", + "street": "ABC st" + }, + "experience": "excellent", + ... + } +``` + +This allows to +```http +GET http://www.example.com/mycompany/Employees + ?$filter=JSON.value(resume,'$.lastname') eq 'Doe' + &$orderby=JSON.value(resume,'$.experience') + &$compute=JSON.query(resume,'$.address') as address + &$expand=address +``` + ## Terms Term|Type|Description :---|:---|:---------- -[Schema](./Org.OData.JSON.V1.xml#L67:~:text=The JSON Schema for JSON values of the annotated property, parameter, return type, term, or type definition
The schema can be a schema reference, i.e. `{"$ref":"url/of/schemafile#/path/to/schema/within/schemafile"}` +[Schema](./Org.OData.JSON.V1.xml#L101:~:text=The JSON Schema for JSON values of the annotated property, parameter, return type, term, or type definition
The schema can be a schema reference, i.e. `{"$ref":"url/of/schemafile#/path/to/schema/within/schemafile"}` ## Functions -### [query](./Org.OData.JSON.V1.xml#L75:~:text=[query](./Org.OData.JSON.V1.xml#L109:~:text=[value](./Org.OData.JSON.V1.xml#L96:~:text=[value](./Org.OData.JSON.V1.xml#L130:~:text=[JSON](./Org.OData.JSON.V1.xml#L122:~:text=[JSON](./Org.OData.JSON.V1.xml#L156:~:text=[Path](./Org.OData.JSON.V1.xml#L133:~:text=[Path](./Org.OData.JSON.V1.xml#L167:~:text= - Terms for JSON properties + Terms, types, and functions for JSON properties + + + +> Motivation from OData Extension for JSON Data - A Directional White Paper + +> Example schema - separate files, link here, show excerpt + +**Example** + +The `Employees` entity set has a property `resume` of type `JSON.JSON`, and one of its entities has a `resume` of +```json +{ + "ssn": "1234", + "lastname": "Doe", + "address": { + "zipcode": "10022", + "street": "ABC st" + }, + "experience": "excellent", + ... + } +``` + +This allows to +```http +GET http://www.example.com/mycompany/Employees + ?$filter=JSON.value(resume,'$.lastname') eq 'Doe' + &$orderby=JSON.value(resume,'$.experience') + &$compute=JSON.query(resume,'$.address') as address + &$expand=address +``` + + + From ec1ec9ca3aba02843ed3d9d2210f5bd7bd514295 Mon Sep 17 00:00:00 2001 From: Ralf Handl Date: Fri, 1 Oct 2021 14:42:20 +0200 Subject: [PATCH 06/31] Long description of the vocabulary --- examples/Org.OData.JSON.V1.Schema-sample.json | 24 +++++- examples/Org.OData.JSON.V1.Schema-sample.xml | 18 ++++- vocabularies/Org.OData.JSON.V1.json | 8 +- vocabularies/Org.OData.JSON.V1.md | 75 +++++++++++++------ vocabularies/Org.OData.JSON.V1.xml | 59 +++++++++++---- 5 files changed, 142 insertions(+), 42 deletions(-) diff --git a/examples/Org.OData.JSON.V1.Schema-sample.json b/examples/Org.OData.JSON.V1.Schema-sample.json index 962d6fdb..32cf3079 100644 --- a/examples/Org.OData.JSON.V1.Schema-sample.json +++ b/examples/Org.OData.JSON.V1.Schema-sample.json @@ -19,6 +19,27 @@ } }, "json.schema.sample": { + "$Alias": "this", + "container": { + "$Kind": "EntityContainer", + "Employees": { + "$Collection": true, + "$Type": "this.Employee" + } + }, + "Employee": { + "$Kind": "EntityType", + "$Key": [ + "empid" + ], + "empid": { + "$Type": "Edm.Int32" + }, + "resume": { + "$Type": "JSON.JSON", + "$Nullable": true + } + }, "example": { "$Kind": "ComplexType", "CodeDictionary": { @@ -37,5 +58,6 @@ } } } - } + }, + "$EntityContainer": "json.schema.sample.container" } \ No newline at end of file diff --git a/examples/Org.OData.JSON.V1.Schema-sample.xml b/examples/Org.OData.JSON.V1.Schema-sample.xml index 6a7999b7..bd73376f 100644 --- a/examples/Org.OData.JSON.V1.Schema-sample.xml +++ b/examples/Org.OData.JSON.V1.Schema-sample.xml @@ -1,4 +1,4 @@ - + @@ -7,7 +7,19 @@ - + + + + + + + + + + + + + @@ -22,4 +34,4 @@ - \ No newline at end of file + diff --git a/vocabularies/Org.OData.JSON.V1.json b/vocabularies/Org.OData.JSON.V1.json index 3c24f3db..e963fea6 100644 --- a/vocabularies/Org.OData.JSON.V1.json +++ b/vocabularies/Org.OData.JSON.V1.json @@ -12,8 +12,8 @@ }, "Org.OData.JSON.V1": { "$Alias": "JSON", - "@Core.Description": "Terms, types, and functions for JSON properties", - "@Core.LongDescription": "\n\n> Motivation from OData Extension for JSON Data - A Directional White Paper \n\n> Example schema - separate files, link here, show excerpt\n\n**Example**\n\nThe `Employees` entity set has a property `resume` of type `JSON.JSON`, and one of its entities has a `resume` of\n```json\n{ \n \"ssn\": \"1234\", \n \"lastname\": \"Doe\", \n \"address\": {\n \"zipcode\": \"10022\", \n \"street\": \"ABC st\"\n },\n \"experience\": \"excellent\", \n ...\n }\n```\n\nThis allows to\n```http\nGET http://www.example.com/mycompany/Employees\n ?$filter=JSON.value(resume,'$.lastname') eq 'Doe'\n &$orderby=JSON.value(resume,'$.experience')\n &$compute=JSON.query(resume,'$.address') as address\n &$expand=address\n```\n ", + "@Core.Description": "Terms, types, and functions for JSON streams", + "@Core.LongDescription": "OData [stream properties](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ManagingStreamProperties) allow embedding data of arbitrary media types,\nand the OData JSON format allows [direct embedding of JSON data](https://docs.oasis-open.org/odata/odata-json-format/v4.01/odata-json-format-v4.01.html#sec_StreamProperty) in request and response payloads.\n \nThis vocabulary defines a convenince [type for JSON streams](#JSON) streams as well as a term for referencing a [JSON Schema](#Schema) describing the structure of the JSON stream. \n\nIn addition it defines two functions for [querying](#query) JSON streams and using a [primitive value](#value) extracted from a JSON stream in common expressions, for example in `$filter`, `$orderby`, or `$compute`.\n\n**Example**\n\nThe `Employees` entity set has a JSON stream property `resume`:\n```json\n\"container\": {\n \"$Kind\": \"EntityContainer\",\n \"Employees\": { \"$Collection\": true, \"$Type\": \"this.Employee\" }\n},\n\"Employee\": {\n \"$Kind\": \"EntityType\",\n \"$Key\": [\"empid\"],\n \"empid\": { \"$Type\": \"Edm.Int32\" },\n \"resume\": { \"$Type\": \"JSON.JSON\", \"$Nullable\": true }\n}\n```\n\nOne of its entities has a `resume` value of\n```json\n{ \n \"ssn\": \"1234\", \n \"lastname\": \"Doe\", \n \"address\": {\n \"zipcode\": \"10022\", \n \"street\": \"ABC st\"\n },\n \"experience\": \"excellent\", \n ...\n}\n```\n\nThis allows to filter and sort by values in that resume, and extract parts of the resume as a dynamic JSON stream property\n```http\nGET http://www.example.com/mycompany/Employees\n ?$filter=resume/JSON.value('$.lastname') eq 'Doe'\n &$orderby=resume/JSON.value('$.experience')\n &$compute=resume/JSON.query('$.address') as address\n &$expand=address\n```\nreceiving\n```json\n{ \n \"@odata.context\": \"$metadata#Employees\", \n \"value\": [ \n {\n \"empid\": 4711,\n \"address\": {\n \"zipcode\": \"10022\", \n \"street\": \"ABC st\"\n }\n },\n ...\n ]\n}\n```\n ", "@Core.Links": [ { "rel": "alternate", @@ -45,6 +45,8 @@ "query": [ { "$Kind": "Function", + "$IsBound": true, + "$IsComposable": true, "@Core.Description": "Query stream values of media type `application/json`, returning a stream value of media type `application/json`", "@Core.LongDescription": "Extracts a JSON value, such as an array, object, or a JSON scalar value (string, number, boolean, or `null`) from the `input` JSON value:\n- If `path` only consists of the root selector followed by member and index selectors, it returns the identified single node within `input`, or `null` if no node is identified. \n- If `path` potentially identifies multiple nodes within `input` (by using descendant, wildcard, union, array subset, or filter selectors), it returns an array containing the identified nodes, or an empty array if no node is identified. \n- If `input` is not a valid JSON value, the function returns `null`.\n- If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input` (for example applying an index selector to a scalar value), the function returns `null`. \n ", "$Parameter": [ @@ -71,6 +73,8 @@ "value": [ { "$Kind": "Function", + "$IsBound": true, + "$IsComposable": true, "@Core.Description": "Query stream values of media type `application/json`, returning an OData primitive value", "@Core.LongDescription": "Extracts a single OData primitive value from the `input` JSON value:\n- If `path` only consists of the root selector followed by member and index selectors and identifies a single scalar JSON value (string, number, boolean, or `null`) within `input`, it returns the identified single value cast to an OData primitive value (see below).\n- If `path` identifies multiple nodes within `input` (by using descendant, wildcard, union, array subset, or filter selectors), identifies an object or array, or does not identify any node, the function returns `null`.\n- If `input` is not a valid JSON value, the function returns `null`.\n- If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input` (for example applying an index selector to a scalar value), the function returns `null`.\n\nIf a single non-null scalar JSON value is identified by `path` within `input`, the function returns that value as an OData primitive value of type\n- `Edm.String` if the value is a JSON string\n- `Edm.Boolean` if the value is `true` or `false`\n- `Edm.Decimal` with unspecified precision and floating scale if the value is a JSON number\n ", "$Parameter": [ diff --git a/vocabularies/Org.OData.JSON.V1.md b/vocabularies/Org.OData.JSON.V1.md index 74047c8a..2a25c205 100644 --- a/vocabularies/Org.OData.JSON.V1.md +++ b/vocabularies/Org.OData.JSON.V1.md @@ -1,17 +1,32 @@ # JSON Vocabulary **Namespace: [Org.OData.JSON.V1](Org.OData.JSON.V1.xml)** -Terms, types, and functions for JSON properties +Terms, types, and functions for JSON streams +OData [stream properties](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ManagingStreamProperties) allow embedding data of arbitrary media types, +and the OData JSON format allows [direct embedding of JSON data](https://docs.oasis-open.org/odata/odata-json-format/v4.01/odata-json-format-v4.01.html#sec_StreamProperty) in request and response payloads. + +This vocabulary defines a convenince [type for JSON streams](#JSON) streams as well as a term for referencing a [JSON Schema](#Schema) describing the structure of the JSON stream. - -> Motivation from OData Extension for JSON Data - A Directional White Paper - -> Example schema - separate files, link here, show excerpt +In addition it defines two functions for [querying](#query) JSON streams and using a [primitive value](#value) extracted from a JSON stream in common expressions, for example in `$filter`, `$orderby`, or `$compute`. **Example** -The `Employees` entity set has a property `resume` of type `JSON.JSON`, and one of its entities has a `resume` of +The `Employees` entity set has a JSON stream property `resume`: +```json +"container": { + "$Kind": "EntityContainer", + "Employees": { "$Collection": true, "$Type": "this.Employee" } +}, +"Employee": { + "$Kind": "EntityType", + "$Key": ["empid"], + "empid": { "$Type": "Edm.Int32" }, + "resume": { "$Type": "JSON.JSON", "$Nullable": true } +} +``` + +One of its entities has a `resume` value of ```json { "ssn": "1234", @@ -22,17 +37,33 @@ The `Employees` entity set has a property `resume` of type `JSON.JSON`, and one }, "experience": "excellent", ... - } +} ``` -This allows to +This allows to filter and sort by values in that resume, and extract parts of the resume as a dynamic JSON stream property ```http GET http://www.example.com/mycompany/Employees - ?$filter=JSON.value(resume,'$.lastname') eq 'Doe' - &$orderby=JSON.value(resume,'$.experience') - &$compute=JSON.query(resume,'$.address') as address + ?$filter=resume/JSON.value('$.lastname') eq 'Doe' + &$orderby=resume/JSON.value('$.experience') + &$compute=resume/JSON.query('$.address') as address &$expand=address ``` +receiving +```json +{ + "@odata.context": "$metadata#Employees", + "value": [ + { + "empid": 4711, + "address": { + "zipcode": "10022", + "street": "ABC st" + } + }, + ... + ] +} +``` @@ -40,12 +71,12 @@ GET http://www.example.com/mycompany/Employees Term|Type|Description :---|:---|:---------- -[Schema](./Org.OData.JSON.V1.xml#L101:~:text=The JSON Schema for JSON values of the annotated property, parameter, return type, term, or type definition
The schema can be a schema reference, i.e. `{"$ref":"url/of/schemafile#/path/to/schema/within/schemafile"}` +[Schema](./Org.OData.JSON.V1.xml#L132:~:text=The JSON Schema for JSON values of the annotated property, parameter, return type, term, or type definition
The schema can be a schema reference, i.e. `{"$ref":"url/of/schemafile#/path/to/schema/within/schemafile"}` ## Functions -### [query](./Org.OData.JSON.V1.xml#L109:~:text=[query](./Org.OData.JSON.V1.xml#L140:~:text=[value](./Org.OData.JSON.V1.xml#L130:~:text=[value](./Org.OData.JSON.V1.xml#L161:~:text=[JSON](./Org.OData.JSON.V1.xml#L156:~:text=[JSON](./Org.OData.JSON.V1.xml#L187:~:text=[Path](./Org.OData.JSON.V1.xml#L167:~:text=[Path](./Org.OData.JSON.V1.xml#L198:~:text= @@ -45,18 +45,33 @@ - Terms, types, and functions for JSON properties + Terms, types, and functions for JSON streams - + OData [stream properties](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ManagingStreamProperties) allow embedding data of arbitrary media types, +and the OData JSON format allows [direct embedding of JSON data](https://docs.oasis-open.org/odata/odata-json-format/v4.01/odata-json-format-v4.01.html#sec_StreamProperty) in request and response payloads. + +This vocabulary defines a convenince [type for JSON streams](#JSON) streams as well as a term for referencing a [JSON Schema](#Schema) describing the structure of the JSON stream. -> Motivation from OData Extension for JSON Data - A Directional White Paper - -> Example schema - separate files, link here, show excerpt +In addition it defines two functions for [querying](#query) JSON streams and using a [primitive value](#value) extracted from a JSON stream in common expressions, for example in `$filter`, `$orderby`, or `$compute`. **Example** -The `Employees` entity set has a property `resume` of type `JSON.JSON`, and one of its entities has a `resume` of +The `Employees` entity set has a JSON stream property `resume`: +```json +"container": { + "$Kind": "EntityContainer", + "Employees": { "$Collection": true, "$Type": "this.Employee" } +}, +"Employee": { + "$Kind": "EntityType", + "$Key": ["empid"], + "empid": { "$Type": "Edm.Int32" }, + "resume": { "$Type": "JSON.JSON", "$Nullable": true } +} +``` + +One of its entities has a `resume` value of ```json { "ssn": "1234", @@ -67,16 +82,32 @@ The `Employees` entity set has a property `resume` of type `JSON.JSON`, and one }, "experience": "excellent", ... - } +} ``` -This allows to +This allows to filter and sort by values in that resume, and extract parts of the resume as a dynamic JSON stream property ```http GET http://www.example.com/mycompany/Employees - ?$filter=JSON.value(resume,'$.lastname') eq 'Doe' - &$orderby=JSON.value(resume,'$.experience') - &$compute=JSON.query(resume,'$.address') as address + ?$filter=resume/JSON.value('$.lastname') eq 'Doe' + &$orderby=resume/JSON.value('$.experience') + &$compute=resume/JSON.query('$.address') as address &$expand=address +``` +receiving +```json +{ + "@odata.context": "$metadata#Employees", + "value": [ + { + "empid": 4711, + "address": { + "zipcode": "10022", + "street": "ABC st" + } + }, + ... + ] +} ``` @@ -106,7 +137,7 @@ GET http://www.example.com/mycompany/Employees
- + Extracts a JSON value, such as an array, object, or a JSON scalar value (string, number, boolean, or `null`) from the `input` JSON value: @@ -127,7 +158,7 @@ GET http://www.example.com/mycompany/Employees - + Extracts a single OData primitive value from the `input` JSON value: From 778d44cacdff64743dfc8a6d9426457f88316652 Mon Sep 17 00:00:00 2001 From: Ralf Handl Date: Fri, 1 Oct 2021 14:44:12 +0200 Subject: [PATCH 07/31] Update Org.OData.JSON.V1.Schema-sample.xml --- examples/Org.OData.JSON.V1.Schema-sample.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/Org.OData.JSON.V1.Schema-sample.xml b/examples/Org.OData.JSON.V1.Schema-sample.xml index bd73376f..4cd067de 100644 --- a/examples/Org.OData.JSON.V1.Schema-sample.xml +++ b/examples/Org.OData.JSON.V1.Schema-sample.xml @@ -10,7 +10,7 @@ - + From d761c8d7a3767c1a6819ba7c85ee8842a060ab42 Mon Sep 17 00:00:00 2001 From: Ralf Handl Date: Fri, 1 Oct 2021 14:51:27 +0200 Subject: [PATCH 08/31] Minor edits --- vocabularies/Org.OData.JSON.V1.json | 10 +++++----- vocabularies/Org.OData.JSON.V1.md | 31 ++++++++++++++--------------- vocabularies/Org.OData.JSON.V1.xml | 11 +++++----- 3 files changed, 25 insertions(+), 27 deletions(-) diff --git a/vocabularies/Org.OData.JSON.V1.json b/vocabularies/Org.OData.JSON.V1.json index e963fea6..a7926cc5 100644 --- a/vocabularies/Org.OData.JSON.V1.json +++ b/vocabularies/Org.OData.JSON.V1.json @@ -13,7 +13,7 @@ "Org.OData.JSON.V1": { "$Alias": "JSON", "@Core.Description": "Terms, types, and functions for JSON streams", - "@Core.LongDescription": "OData [stream properties](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ManagingStreamProperties) allow embedding data of arbitrary media types,\nand the OData JSON format allows [direct embedding of JSON data](https://docs.oasis-open.org/odata/odata-json-format/v4.01/odata-json-format-v4.01.html#sec_StreamProperty) in request and response payloads.\n \nThis vocabulary defines a convenince [type for JSON streams](#JSON) streams as well as a term for referencing a [JSON Schema](#Schema) describing the structure of the JSON stream. \n\nIn addition it defines two functions for [querying](#query) JSON streams and using a [primitive value](#value) extracted from a JSON stream in common expressions, for example in `$filter`, `$orderby`, or `$compute`.\n\n**Example**\n\nThe `Employees` entity set has a JSON stream property `resume`:\n```json\n\"container\": {\n \"$Kind\": \"EntityContainer\",\n \"Employees\": { \"$Collection\": true, \"$Type\": \"this.Employee\" }\n},\n\"Employee\": {\n \"$Kind\": \"EntityType\",\n \"$Key\": [\"empid\"],\n \"empid\": { \"$Type\": \"Edm.Int32\" },\n \"resume\": { \"$Type\": \"JSON.JSON\", \"$Nullable\": true }\n}\n```\n\nOne of its entities has a `resume` value of\n```json\n{ \n \"ssn\": \"1234\", \n \"lastname\": \"Doe\", \n \"address\": {\n \"zipcode\": \"10022\", \n \"street\": \"ABC st\"\n },\n \"experience\": \"excellent\", \n ...\n}\n```\n\nThis allows to filter and sort by values in that resume, and extract parts of the resume as a dynamic JSON stream property\n```http\nGET http://www.example.com/mycompany/Employees\n ?$filter=resume/JSON.value('$.lastname') eq 'Doe'\n &$orderby=resume/JSON.value('$.experience')\n &$compute=resume/JSON.query('$.address') as address\n &$expand=address\n```\nreceiving\n```json\n{ \n \"@odata.context\": \"$metadata#Employees\", \n \"value\": [ \n {\n \"empid\": 4711,\n \"address\": {\n \"zipcode\": \"10022\", \n \"street\": \"ABC st\"\n }\n },\n ...\n ]\n}\n```\n ", + "@Core.LongDescription": "OData [stream properties](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ManagingStreamProperties) allow embedding data of arbitrary media types,\nand the OData JSON format allows [direct embedding of JSON data](https://docs.oasis-open.org/odata/odata-json-format/v4.01/odata-json-format-v4.01.html#sec_StreamProperty) in request and response payloads.\n \nThis vocabulary defines a convenince [type for JSON streams](#JSON) streams as well as a term for referencing a [JSON Schema](#Schema) describing the structure of the JSON stream. \n\nIn addition it defines two functions for [querying](#query) JSON streams and using a [primitive value](#value) extracted from a JSON stream in common expressions, for example in `$filter`, `$orderby`, or `$compute`.\n\n**Example**\n\nThe `Employees` entity set has a JSON stream property `resume`:\n```json\n\"container\": {\n \"$Kind\": \"EntityContainer\",\n \"Employees\": { \"$Collection\": true, \"$Type\": \"this.Employee\" }\n},\n\"Employee\": {\n \"$Kind\": \"EntityType\",\n \"$Key\": [\"empid\"],\n \"empid\": { \"$Type\": \"Edm.Int32\" },\n \"resume\": { \"$Type\": \"JSON.JSON\", \"$Nullable\": true }\n}\n```\n\nOne of its entities has a `resume` value of\n```json\n{ \n \"ssn\": \"1234\", \n \"lastname\": \"Doe\", \n \"address\": {\n \"zipcode\": \"10022\", \n \"street\": \"ABC st\"\n },\n \"experience\": \"excellent\"\n}\n```\n\nThis allows to filter and sort by values in that resume, and extract parts of the resume as a dynamic JSON stream property\n```http\nGET http://www.example.com/mycompany/Employees\n ?$filter=resume/JSON.value('$.lastname') eq 'Doe'\n &$orderby=resume/JSON.value('$.experience')\n &$compute=resume/JSON.query('$.address') as address\n &$expand=address\n```\nreceiving\n```json\n{ \n \"@odata.context\": \"$metadata#Employees\", \n \"value\": [ \n {\n \"empid\": 4711,\n \"address\": {\n \"zipcode\": \"10022\", \n \"street\": \"ABC st\"\n }\n },\n ...\n ]\n}\n```\n ", "@Core.Links": [ { "rel": "alternate", @@ -40,14 +40,14 @@ ], "@Core.RequiresType": "Edm.Stream", "@Core.Description": "The JSON Schema for JSON values of the annotated property, parameter, return type, term, or type definition", - "@Core.LongDescription": "The schema can be a schema reference, i.e. `{\"$ref\":\"url/of/schemafile#/path/to/schema/within/schemafile\"}`" + "@Core.LongDescription": "The schema can be a reference, i.e. `{\"$ref\":\"url/of/schemafile#/path/to/schema/within/schemafile\"}`" }, "query": [ { "$Kind": "Function", "$IsBound": true, "$IsComposable": true, - "@Core.Description": "Query stream values of media type `application/json`, returning a stream value of media type `application/json`", + "@Core.Description": "Query a stream value of media type `application/json`, returning a stream value of media type `application/json`", "@Core.LongDescription": "Extracts a JSON value, such as an array, object, or a JSON scalar value (string, number, boolean, or `null`) from the `input` JSON value:\n- If `path` only consists of the root selector followed by member and index selectors, it returns the identified single node within `input`, or `null` if no node is identified. \n- If `path` potentially identifies multiple nodes within `input` (by using descendant, wildcard, union, array subset, or filter selectors), it returns an array containing the identified nodes, or an empty array if no node is identified. \n- If `input` is not a valid JSON value, the function returns `null`.\n- If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input` (for example applying an index selector to a scalar value), the function returns `null`. \n ", "$Parameter": [ { @@ -75,7 +75,7 @@ "$Kind": "Function", "$IsBound": true, "$IsComposable": true, - "@Core.Description": "Query stream values of media type `application/json`, returning an OData primitive value", + "@Core.Description": "Query a stream value of media type `application/json`, returning an OData primitive value", "@Core.LongDescription": "Extracts a single OData primitive value from the `input` JSON value:\n- If `path` only consists of the root selector followed by member and index selectors and identifies a single scalar JSON value (string, number, boolean, or `null`) within `input`, it returns the identified single value cast to an OData primitive value (see below).\n- If `path` identifies multiple nodes within `input` (by using descendant, wildcard, union, array subset, or filter selectors), identifies an object or array, or does not identify any node, the function returns `null`.\n- If `input` is not a valid JSON value, the function returns `null`.\n- If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input` (for example applying an index selector to a scalar value), the function returns `null`.\n\nIf a single non-null scalar JSON value is identified by `path` within `input`, the function returns that value as an OData primitive value of type\n- `Edm.String` if the value is a JSON string\n- `Edm.Boolean` if the value is `true` or `false`\n- `Edm.Decimal` with unspecified precision and floating scale if the value is a JSON number\n ", "$Parameter": [ { @@ -111,7 +111,7 @@ "$Kind": "TypeDefinition", "$UnderlyingType": "Edm.String", "@Core.Description": "[JSONPath](https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-01) expression", - "@Core.LongDescription": "Implementations SHOULD support at least the following subset of JSONPath:\n\nJSONPath | Description | Examples\n---------|-------------|--------\n`$` | Root selector | `$`\n`.` | Member selector | `$.foo`, `$.foo.bar`\n`[]` | Index selector with member name (single- or double-quoted string using JSON escaping rules) or zero-based array index (non-negative base-10 integer) | `$['foo']`, `$.foo[\"bar\"]`, `$.bar[0]`, `$.bar[42]`\n\nImplementations MAY support in addition:\n\nJSONPath | Description | Examples\n---------|-------------|--------\n`[]` | Index selector with negative integer array index (counts from the end of the array) | `$.bar[-1]`\n`..` | Descendant selector: searches for the specified member name recursively and returns an array of all values with this member name | `$..foo`\n`*` | Wildcard selector matching all elements in an object or array | `$.foo.*`, `$.bar[*]`, `$..*`\n`[,]` | Union selector for alternate member names or array indices as a set | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]`\n`[start:end]` | Array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:5]`, same as `$.bar[2,3,4]`\n`[start:]` | Array subset from _start_ to end of array | `$.bar[2:]`\n`[:n]` | The first _n_ array items | `$.bar[:4]`\n`[-n:]` | The last _n_ array items | `$.bar[-3:]`\n`[start:end:step]` | [Array slice selector](https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-01#section-3.5.6) |\n`[?()]` | Filter selector | `$.bar[?(@.baz==42)]`\n`()` | Static expression | `$.bar[(@.length-1)]`\n`@` | in expressions: the current node being processed\n\n**References**\n- Current IETF draft: https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-01\n- Historic site: https://goessner.net/articles/JsonPath/\n- Node.js implementation: https://www.npmjs.com/package/jsonpath\n- Java implementation: https://github.com/json-path/JsonPath\n- Online evaluator: https://jsonpath.com/\n " + "@Core.LongDescription": "Implementations SHOULD support at least the following subset of JSONPath:\n\nJSONPath | Description | Examples\n---------|-------------|--------\n`$` | Root selector | `$`\n`.` | Member selector | `$.foo`, `$.foo.bar`\n`[]` | Index selector with member name (single- or double-quoted string using JSON escaping rules) or zero-based array index (non-negative base-10 integer) | `$['foo']`, `$.foo[\"bar\"]`, `$.bar[0]`, `$.bar[42]`\n\nImplementations MAY support in addition:\n\nJSONPath | Description | Examples\n---------|-------------|--------\n`[]` | Index selector with negative integer array index (counts from the end of the array) | `$.bar[-1]`\n`..` | Descendant selector: searches for the specified member name recursively and returns an array of all values with this member name | `$..foo`\n`*` | Wildcard selector matching all elements in an object or array | `$.foo.*`, `$.bar[*]`, `$..*`\n`[,]` | Union selector for alternate member names or array indices as a set | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]`\n`[start:end]` | Array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:5]`, same as `$.bar[2,3,4]`\n`[start:]` | Array subset from _start_ to end of array | `$.bar[2:]`\n`[:n]` | The first _n_ array items | `$.bar[:4]`\n`[-n:]` | The last _n_ array items | `$.bar[-3:]`\n`[start:end:step]` | [Array slice selector](https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-01#section-3.5.6) |\n`[?()]` | Filter selector | `$.bar[?(@.baz==42)]`\n`()` | Static expression | `$.bar[(@.length-1)]`\n`@` | in expressions: the current node being processed\n\n**References for JSONPath**\n- Current IETF draft: https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-01\n- Historic site: https://goessner.net/articles/JsonPath/\n- Node.js implementation: https://www.npmjs.com/package/jsonpath\n- Java implementation: https://github.com/json-path/JsonPath\n- Online evaluator: https://jsonpath.com/\n " } } } \ No newline at end of file diff --git a/vocabularies/Org.OData.JSON.V1.md b/vocabularies/Org.OData.JSON.V1.md index 2a25c205..c912b25b 100644 --- a/vocabularies/Org.OData.JSON.V1.md +++ b/vocabularies/Org.OData.JSON.V1.md @@ -35,8 +35,7 @@ One of its entities has a `resume` value of "zipcode": "10022", "street": "ABC st" }, - "experience": "excellent", - ... + "experience": "excellent" } ``` @@ -71,14 +70,14 @@ receiving Term|Type|Description :---|:---|:---------- -[Schema](./Org.OData.JSON.V1.xml#L132:~:text=The JSON Schema for JSON values of the annotated property, parameter, return type, term, or type definition
The schema can be a schema reference, i.e. `{"$ref":"url/of/schemafile#/path/to/schema/within/schemafile"}` +[Schema](./Org.OData.JSON.V1.xml#L131:~:text=The JSON Schema for JSON values of the annotated property, parameter, return type, term, or type definition
The schema can be a reference, i.e. `{"$ref":"url/of/schemafile#/path/to/schema/within/schemafile"}` ## Functions -### [query](./Org.OData.JSON.V1.xml#L140:~:text=[query](./Org.OData.JSON.V1.xml#L139:~:text=[value](./Org.OData.JSON.V1.xml#L161:~:text=[value](./Org.OData.JSON.V1.xml#L160:~:text=[JSON](./Org.OData.JSON.V1.xml#L187:~:text=[JSON](./Org.OData.JSON.V1.xml#L186:~:text=[Path](./Org.OData.JSON.V1.xml#L198:~:text=[Path](./Org.OData.JSON.V1.xml#L197:~:text= - The schema can be a schema reference, i.e. `{"$ref":"url/of/schemafile#/path/to/schema/within/schemafile"}` + The schema can be a reference, i.e. `{"$ref":"url/of/schemafile#/path/to/schema/within/schemafile"}` - + Extracts a JSON value, such as an array, object, or a JSON scalar value (string, number, boolean, or `null`) from the `input` JSON value: - If `path` only consists of the root selector followed by member and index selectors, it returns the identified single node within `input`, or `null` if no node is identified. @@ -159,7 +158,7 @@ receiving - + Extracts a single OData primitive value from the `input` JSON value: - If `path` only consists of the root selector followed by member and index selectors and identifies a single scalar JSON value (string, number, boolean, or `null`) within `input`, it returns the identified single value cast to an OData primitive value (see below). @@ -223,7 +222,7 @@ JSONPath | Description | Examples `()` | Static expression | `$.bar[(@.length-1)]` `@` | in expressions: the current node being processed -**References** +**References for JSONPath** - Current IETF draft: https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-01 - Historic site: https://goessner.net/articles/JsonPath/ - Node.js implementation: https://www.npmjs.com/package/jsonpath From 5ede455cefda53d5cb067b194609db2fcd3e22ab Mon Sep 17 00:00:00 2001 From: Ralf Handl Date: Fri, 1 Oct 2021 16:37:38 +0200 Subject: [PATCH 09/31] Update Org.OData.JSON.V1.xml --- vocabularies/Org.OData.JSON.V1.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vocabularies/Org.OData.JSON.V1.xml b/vocabularies/Org.OData.JSON.V1.xml index 22607fb9..e97152ce 100644 --- a/vocabularies/Org.OData.JSON.V1.xml +++ b/vocabularies/Org.OData.JSON.V1.xml @@ -157,7 +157,7 @@ receiving - + Extracts a single OData primitive value from the `input` JSON value: From f9d2a37b84be56862400e07b7638ceaae674c195 Mon Sep 17 00:00:00 2001 From: Ralf Handl Date: Fri, 1 Oct 2021 16:38:17 +0200 Subject: [PATCH 10/31] Function "value" isn't composable --- vocabularies/Org.OData.JSON.V1.json | 1 - 1 file changed, 1 deletion(-) diff --git a/vocabularies/Org.OData.JSON.V1.json b/vocabularies/Org.OData.JSON.V1.json index a7926cc5..6a43523a 100644 --- a/vocabularies/Org.OData.JSON.V1.json +++ b/vocabularies/Org.OData.JSON.V1.json @@ -74,7 +74,6 @@ { "$Kind": "Function", "$IsBound": true, - "$IsComposable": true, "@Core.Description": "Query a stream value of media type `application/json`, returning an OData primitive value", "@Core.LongDescription": "Extracts a single OData primitive value from the `input` JSON value:\n- If `path` only consists of the root selector followed by member and index selectors and identifies a single scalar JSON value (string, number, boolean, or `null`) within `input`, it returns the identified single value cast to an OData primitive value (see below).\n- If `path` identifies multiple nodes within `input` (by using descendant, wildcard, union, array subset, or filter selectors), identifies an object or array, or does not identify any node, the function returns `null`.\n- If `input` is not a valid JSON value, the function returns `null`.\n- If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input` (for example applying an index selector to a scalar value), the function returns `null`.\n\nIf a single non-null scalar JSON value is identified by `path` within `input`, the function returns that value as an OData primitive value of type\n- `Edm.String` if the value is a JSON string\n- `Edm.Boolean` if the value is `true` or `false`\n- `Edm.Decimal` with unspecified precision and floating scale if the value is a JSON number\n ", "$Parameter": [ From c5b8c7f9399b602667a28cb7e17d0673a7222642 Mon Sep 17 00:00:00 2001 From: Ralf Handl Date: Fri, 22 Sep 2023 11:42:06 +0200 Subject: [PATCH 11/31] Use JSONPath draft 20 --- vocabularies/Org.OData.JSON.V1.json | 8 ++--- vocabularies/Org.OData.JSON.V1.md | 48 +++++++++++++++-------------- vocabularies/Org.OData.JSON.V1.xml | 48 +++++++++++++++-------------- 3 files changed, 54 insertions(+), 50 deletions(-) diff --git a/vocabularies/Org.OData.JSON.V1.json b/vocabularies/Org.OData.JSON.V1.json index 3dc1eb0d..c429fbe2 100644 --- a/vocabularies/Org.OData.JSON.V1.json +++ b/vocabularies/Org.OData.JSON.V1.json @@ -49,7 +49,7 @@ "$IsBound": true, "$IsComposable": true, "@Core.Description": "Query a stream value of media type `application/json`, returning a stream value of media type `application/json`", - "@Core.LongDescription": "Extracts a JSON value, such as an array, object, or a JSON scalar value (string, number, boolean, or `null`) from the `input` JSON value:\n- If `path` only consists of the root selector followed by member and index selectors, it returns the identified single node within `input`, or `null` if no node is identified. \n- If `path` potentially identifies multiple nodes within `input` (by using descendant, wildcard, union, array subset, or filter selectors), it returns an array containing the identified nodes, or an empty array if no node is identified. \n- If `input` is not a valid JSON value, the function returns `null`.\n- If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input` (for example applying an index selector to a scalar value), the function returns `null`. \n ", + "@Core.LongDescription": "Extracts a JSON value, such as an array, object, or a JSON scalar value (string, number, boolean, or `null`) from the `input` JSON value:\n- If `path` only consists of the root identifier followed by name and index selectors, it returns the identified single node within `input`, or `null` if no node is identified. \n- If `path` potentially identifies multiple nodes within `input` (by using descendant, wildcard, union, array subset, or filter selectors), it returns an array containing the identified nodes, or an empty array if no node is identified. \n- If `input` is not a valid JSON value, the function returns `null`.\n- If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input` (for example applying an index selector to a scalar value), the function returns `null`. \n ", "$Parameter": [ { "$Name": "input", @@ -76,7 +76,7 @@ "$Kind": "Function", "$IsBound": true, "@Core.Description": "Query a stream value of media type `application/json`, returning an OData primitive value", - "@Core.LongDescription": "Extracts a single OData primitive value from the `input` JSON value:\n- If `path` only consists of the root selector followed by member and index selectors and identifies a single scalar JSON value (string, number, boolean, or `null`) within `input`, it returns the identified single value cast to an OData primitive value (see below).\n- If `path` identifies multiple nodes within `input` (by using descendant, wildcard, union, array subset, or filter selectors), identifies an object or array, or does not identify any node, the function returns `null`.\n- If `input` is not a valid JSON value, the function returns `null`.\n- If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input` (for example applying an index selector to a scalar value), the function returns `null`.\n\nIf a single non-null scalar JSON value is identified by `path` within `input`, the function returns that value as an OData primitive value of type\n- `Edm.String` if the value is a JSON string\n- `Edm.Boolean` if the value is `true` or `false`\n- `Edm.Decimal` with unspecified precision and floating scale if the value is a JSON number\n ", + "@Core.LongDescription": "Extracts a single OData primitive value from the `input` JSON value:\n- If `path` only consists of the root identifier followed by name and index selectors and identifies a single scalar JSON value (string, number, boolean, or `null`) within `input`, it returns the identified single value cast to an OData primitive value (see below).\n- If `path` identifies multiple nodes within `input` (by using descendant, wildcard, union, array subset, or filter selectors), identifies an object or array, or does not identify any node, the function returns `null`.\n- If `input` is not a valid JSON value, the function returns `null`.\n- If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input` (for example applying an index selector to a scalar value), the function returns `null`.\n\nIf a single non-null scalar JSON value is identified by `path` within `input`, the function returns that value as an OData primitive value of type\n- `Edm.String` if the value is a JSON string\n- `Edm.Boolean` if the value is `true` or `false`\n- `Edm.Decimal` with unspecified precision and floating scale if the value is a JSON number\n ", "$Parameter": [ { "$Name": "input", @@ -110,8 +110,8 @@ "Path": { "$Kind": "TypeDefinition", "$UnderlyingType": "Edm.String", - "@Core.Description": "[JSONPath](https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-01) expression", - "@Core.LongDescription": "Implementations SHOULD support at least the following subset of JSONPath:\n\nJSONPath | Description | Examples\n---------|-------------|--------\n`$` | Root selector | `$`\n`.` | Member selector | `$.foo`, `$.foo.bar`\n`[]` | Index selector with member name (single- or double-quoted string using JSON escaping rules) or zero-based array index (non-negative base-10 integer) | `$['foo']`, `$.foo[\"bar\"]`, `$.bar[0]`, `$.bar[42]`\n\nImplementations MAY support in addition:\n\nJSONPath | Description | Examples\n---------|-------------|--------\n`[]` | Index selector with negative integer array index (counts from the end of the array) | `$.bar[-1]`\n`..` | Descendant selector: searches for the specified member name recursively and returns an array of all values with this member name | `$..foo`\n`*` | Wildcard selector matching all elements in an object or array | `$.foo.*`, `$.bar[*]`, `$..*`\n`[,]` | Union selector for alternate member names or array indices as a set | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]`\n`[start:end]` | Array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:5]`, same as `$.bar[2,3,4]`\n`[start:]` | Array subset from _start_ to end of array | `$.bar[2:]`\n`[:n]` | The first _n_ array items | `$.bar[:4]`\n`[-n:]` | The last _n_ array items | `$.bar[-3:]`\n`[start:end:step]` | [Array slice selector](https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-01#section-3.5.6) |\n`[?()]` | Filter selector | `$.bar[?(@.baz==42)]`\n`()` | Static expression | `$.bar[(@.length-1)]`\n`@` | in expressions: the current node being processed\n\n**References for JSONPath**\n- Current IETF draft: https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-01\n- Historic site: https://goessner.net/articles/JsonPath/\n- Node.js implementation: https://www.npmjs.com/package/jsonpath\n- Java implementation: https://github.com/json-path/JsonPath\n- Online evaluator: https://jsonpath.com/\n " + "@Core.Description": "[JSONPath](https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-20) expression", + "@Core.LongDescription": "Implementations SHOULD support at least the following subset of JSONPath:\n\nSyntax Element | Description | Examples\n---------------|-------------|--------\n`$` | [root identifier](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#root-identifier) | `$`\n`[]` | [child segment](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#child-segment) selects one child of a node; contains one [name selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#name-selector) (single- or double-quoted string using JSON escaping rules) or [index selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#index-selector) (non-negative decimal integer) | `$['foo']`, `$.foo[\"bar\"]`, `$.bar[0]`, `$.bar[42]`\n`.name` | shorthand for `['name']` | `$.foo`, `$.foo.bar`, `$.bar[42].baz`\n\nImplementations MAY support in addition:\n\nSyntax Element | Description | Examples\n---------------|-------------|--------\n`[]` | index selector with negative integer array index (counts from the end of the array) | `$.bar[-1]`\n`[]` | non-empty, comma-separated sequence of selectors | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]`\n`..[]` | [descendant segment](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#descendant-segment): selects zero or more descendants of a node; contains one or more selectors, separated by commas | `$.foo..[\"bar\"]`\n`..name` | shorthand for `..['name']` | `$.foo..bar`\n`*` | [wildcard selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#name-selector): selects all children of a node | `$.foo[*]`, `$[*]`\n`.*` | shorthand for `.[*]` | `$.foo.*`, `$.*`\n`..*` | shorthand for `..[*]` | `$.foo..*`, `$..*`\n`[start:end]` | array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:5]`, same as `$.bar[2,3,4]`\n`[start:]` | array subset from _start_ to end of array | `$.bar[2:]`\n`[:n]` | the first _n_ array items | `$.bar[:4]`\n`[-n:]` | the last _n_ array items | `$.bar[-3:]`\n`[start:end:step]` | [array slice selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#slice) |\n`[?]` | [filter selector](): selects particular children using a logical expression | \n`@` | [current node identifier](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#filter-selector) (valid only within filter selectors) | `$.bar[?@.baz==42]`\n\n**References for JSONPath**\n- Current IETF draft: https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-20\n- Historic site: https://goessner.net/articles/JsonPath/\n- Node.js implementation: https://www.npmjs.com/package/jsonpath\n- Java implementation: https://github.com/json-path/JsonPath\n- Online evaluator: https://jsonpath.com/\n " } } } \ No newline at end of file diff --git a/vocabularies/Org.OData.JSON.V1.md b/vocabularies/Org.OData.JSON.V1.md index d04b0f06..8538e68a 100644 --- a/vocabularies/Org.OData.JSON.V1.md +++ b/vocabularies/Org.OData.JSON.V1.md @@ -81,7 +81,7 @@ Term|Type|Description Query a stream value of media type `application/json`, returning a stream value of media type `application/json` Extracts a JSON value, such as an array, object, or a JSON scalar value (string, number, boolean, or `null`) from the `input` JSON value: -- If `path` only consists of the root selector followed by member and index selectors, it returns the identified single node within `input`, or `null` if no node is identified. +- If `path` only consists of the root identifier followed by name and index selectors, it returns the identified single node within `input`, or `null` if no node is identified. - If `path` potentially identifies multiple nodes within `input` (by using descendant, wildcard, union, array subset, or filter selectors), it returns an array containing the identified nodes, or an empty array if no node is identified. - If `input` is not a valid JSON value, the function returns `null`. - If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input` (for example applying an index selector to a scalar value), the function returns `null`. @@ -100,7 +100,7 @@ Parameter|Type|Description Query a stream value of media type `application/json`, returning an OData primitive value Extracts a single OData primitive value from the `input` JSON value: -- If `path` only consists of the root selector followed by member and index selectors and identifies a single scalar JSON value (string, number, boolean, or `null`) within `input`, it returns the identified single value cast to an OData primitive value (see below). +- If `path` only consists of the root identifier followed by name and index selectors and identifies a single scalar JSON value (string, number, boolean, or `null`) within `input`, it returns the identified single value cast to an OData primitive value (see below). - If `path` identifies multiple nodes within `input` (by using descendant, wildcard, union, array subset, or filter selectors), identifies an object or array, or does not identify any node, the function returns `null`. - If `input` is not a valid JSON value, the function returns `null`. - If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input` (for example applying an index selector to a scalar value), the function returns `null`. @@ -128,35 +128,37 @@ Textual data of media type `application/json` ## [Path](./Org.OData.JSON.V1.xml#L197:~:text=]` | [child segment](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#child-segment) selects one child of a node; contains one [name selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#name-selector) (single- or double-quoted string using JSON escaping rules) or [index selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#index-selector) (non-negative decimal integer) | `$['foo']`, `$.foo["bar"]`, `$.bar[0]`, `$.bar[42]` +`.name` | shorthand for `['name']` | `$.foo`, `$.foo.bar`, `$.bar[42].baz` Implementations MAY support in addition: -JSONPath | Description | Examples ----------|-------------|-------- -`[]` | Index selector with negative integer array index (counts from the end of the array) | `$.bar[-1]` -`..` | Descendant selector: searches for the specified member name recursively and returns an array of all values with this member name | `$..foo` -`*` | Wildcard selector matching all elements in an object or array | `$.foo.*`, `$.bar[*]`, `$..*` -`[,]` | Union selector for alternate member names or array indices as a set | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]` -`[start:end]` | Array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:5]`, same as `$.bar[2,3,4]` -`[start:]` | Array subset from _start_ to end of array | `$.bar[2:]` -`[:n]` | The first _n_ array items | `$.bar[:4]` -`[-n:]` | The last _n_ array items | `$.bar[-3:]` -`[start:end:step]` | [Array slice selector](https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-01#section-3.5.6) | -`[?()]` | Filter selector | `$.bar[?(@.baz==42)]` -`()` | Static expression | `$.bar[(@.length-1)]` -`@` | in expressions: the current node being processed +Syntax Element | Description | Examples +---------------|-------------|-------- +`[]` | index selector with negative integer array index (counts from the end of the array) | `$.bar[-1]` +`[]` | non-empty, comma-separated sequence of selectors | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]` +`..[]` | [descendant segment](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#descendant-segment): selects zero or more descendants of a node; contains one or more selectors, separated by commas | `$.foo..["bar"]` +`..name` | shorthand for `..['name']` | `$.foo..bar` +`*` | [wildcard selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#name-selector): selects all children of a node | `$.foo[*]`, `$[*]` +`.*` | shorthand for `.[*]` | `$.foo.*`, `$.*` +`..*` | shorthand for `..[*]` | `$.foo..*`, `$..*` +`[start:end]` | array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:5]`, same as `$.bar[2,3,4]` +`[start:]` | array subset from _start_ to end of array | `$.bar[2:]` +`[:n]` | the first _n_ array items | `$.bar[:4]` +`[-n:]` | the last _n_ array items | `$.bar[-3:]` +`[start:end:step]` | [array slice selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#slice) | +`[?]` | [filter selector](): selects particular children using a logical expression | +`@` | [current node identifier](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#filter-selector) (valid only within filter selectors) | `$.bar[?@.baz==42]` **References for JSONPath** -- Current IETF draft: https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-01 +- Current IETF draft: https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-20 - Historic site: https://goessner.net/articles/JsonPath/ - Node.js implementation: https://www.npmjs.com/package/jsonpath - Java implementation: https://github.com/json-path/JsonPath diff --git a/vocabularies/Org.OData.JSON.V1.xml b/vocabularies/Org.OData.JSON.V1.xml index 5d9eafc9..c5cb548a 100644 --- a/vocabularies/Org.OData.JSON.V1.xml +++ b/vocabularies/Org.OData.JSON.V1.xml @@ -140,7 +140,7 @@ receiving Extracts a JSON value, such as an array, object, or a JSON scalar value (string, number, boolean, or `null`) from the `input` JSON value: -- If `path` only consists of the root selector followed by member and index selectors, it returns the identified single node within `input`, or `null` if no node is identified. +- If `path` only consists of the root identifier followed by name and index selectors, it returns the identified single node within `input`, or `null` if no node is identified. - If `path` potentially identifies multiple nodes within `input` (by using descendant, wildcard, union, array subset, or filter selectors), it returns an array containing the identified nodes, or an empty array if no node is identified. - If `input` is not a valid JSON value, the function returns `null`. - If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input` (for example applying an index selector to a scalar value), the function returns `null`. @@ -161,7 +161,7 @@ receiving Extracts a single OData primitive value from the `input` JSON value: -- If `path` only consists of the root selector followed by member and index selectors and identifies a single scalar JSON value (string, number, boolean, or `null`) within `input`, it returns the identified single value cast to an OData primitive value (see below). +- If `path` only consists of the root identifier followed by name and index selectors and identifies a single scalar JSON value (string, number, boolean, or `null`) within `input`, it returns the identified single value cast to an OData primitive value (see below). - If `path` identifies multiple nodes within `input` (by using descendant, wildcard, union, array subset, or filter selectors), identifies an object or array, or does not identify any node, the function returns `null`. - If `input` is not a valid JSON value, the function returns `null`. - If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input` (for example applying an index selector to a scalar value), the function returns `null`. @@ -195,35 +195,37 @@ If a single non-null scalar JSON value is identified by `path` within `input`, t - + Implementations SHOULD support at least the following subset of JSONPath: -JSONPath | Description | Examples ----------|-------------|-------- -`$` | Root selector | `$` -`.` | Member selector | `$.foo`, `$.foo.bar` -`[]` | Index selector with member name (single- or double-quoted string using JSON escaping rules) or zero-based array index (non-negative base-10 integer) | `$['foo']`, `$.foo["bar"]`, `$.bar[0]`, `$.bar[42]` +Syntax Element | Description | Examples +---------------|-------------|-------- +`$` | [root identifier](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#root-identifier) | `$` +`[<selector>]` | [child segment](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#child-segment) selects one child of a node; contains one [name selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#name-selector) (single- or double-quoted string using JSON escaping rules) or [index selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#index-selector) (non-negative decimal integer) | `$['foo']`, `$.foo["bar"]`, `$.bar[0]`, `$.bar[42]` +`.name` | shorthand for `['name']` | `$.foo`, `$.foo.bar`, `$.bar[42].baz` Implementations MAY support in addition: -JSONPath | Description | Examples ----------|-------------|-------- -`[]` | Index selector with negative integer array index (counts from the end of the array) | `$.bar[-1]` -`..` | Descendant selector: searches for the specified member name recursively and returns an array of all values with this member name | `$..foo` -`*` | Wildcard selector matching all elements in an object or array | `$.foo.*`, `$.bar[*]`, `$..*` -`[,]` | Union selector for alternate member names or array indices as a set | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]` -`[start:end]` | Array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:5]`, same as `$.bar[2,3,4]` -`[start:]` | Array subset from _start_ to end of array | `$.bar[2:]` -`[:n]` | The first _n_ array items | `$.bar[:4]` -`[-n:]` | The last _n_ array items | `$.bar[-3:]` -`[start:end:step]` | [Array slice selector](https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-01#section-3.5.6) | -`[?()]` | Filter selector | `$.bar[?(@.baz==42)]` -`()` | Static expression | `$.bar[(@.length-1)]` -`@` | in expressions: the current node being processed +Syntax Element | Description | Examples +---------------|-------------|-------- +`[<selector>]` | index selector with negative integer array index (counts from the end of the array) | `$.bar[-1]` +`[<selectors>]` | non-empty, comma-separated sequence of selectors | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]` +`..[<selectors>]` | [descendant segment](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#descendant-segment): selects zero or more descendants of a node; contains one or more selectors, separated by commas | `$.foo..["bar"]` +`..name` | shorthand for `..['name']` | `$.foo..bar` +`*` | [wildcard selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#name-selector): selects all children of a node | `$.foo[*]`, `$[*]` +`.*` | shorthand for `.[*]` | `$.foo.*`, `$.*` +`..*` | shorthand for `..[*]` | `$.foo..*`, `$..*` +`[start:end]` | array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:5]`, same as `$.bar[2,3,4]` +`[start:]` | array subset from _start_ to end of array | `$.bar[2:]` +`[:n]` | the first _n_ array items | `$.bar[:4]` +`[-n:]` | the last _n_ array items | `$.bar[-3:]` +`[start:end:step]` | [array slice selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#slice) | +`[?<logical-expr>]` | [filter selector](): selects particular children using a logical expression | +`@` | [current node identifier](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#filter-selector) (valid only within filter selectors) | `$.bar[?@.baz==42]` **References for JSONPath** -- Current IETF draft: https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-01 +- Current IETF draft: https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-20 - Historic site: https://goessner.net/articles/JsonPath/ - Node.js implementation: https://www.npmjs.com/package/jsonpath - Java implementation: https://github.com/json-path/JsonPath From b83f15af3b1658b5abd0d7513a2829447bd35623 Mon Sep 17 00:00:00 2001 From: Ralf Handl Date: Fri, 22 Sep 2023 11:47:50 +0200 Subject: [PATCH 12/31] Updated URLs --- vocabularies/Org.OData.JSON.V1.json | 4 ++-- vocabularies/Org.OData.JSON.V1.md | 4 ++-- vocabularies/Org.OData.JSON.V1.xml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/vocabularies/Org.OData.JSON.V1.json b/vocabularies/Org.OData.JSON.V1.json index c429fbe2..745cc6b5 100644 --- a/vocabularies/Org.OData.JSON.V1.json +++ b/vocabularies/Org.OData.JSON.V1.json @@ -110,8 +110,8 @@ "Path": { "$Kind": "TypeDefinition", "$UnderlyingType": "Edm.String", - "@Core.Description": "[JSONPath](https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-20) expression", - "@Core.LongDescription": "Implementations SHOULD support at least the following subset of JSONPath:\n\nSyntax Element | Description | Examples\n---------------|-------------|--------\n`$` | [root identifier](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#root-identifier) | `$`\n`[]` | [child segment](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#child-segment) selects one child of a node; contains one [name selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#name-selector) (single- or double-quoted string using JSON escaping rules) or [index selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#index-selector) (non-negative decimal integer) | `$['foo']`, `$.foo[\"bar\"]`, `$.bar[0]`, `$.bar[42]`\n`.name` | shorthand for `['name']` | `$.foo`, `$.foo.bar`, `$.bar[42].baz`\n\nImplementations MAY support in addition:\n\nSyntax Element | Description | Examples\n---------------|-------------|--------\n`[]` | index selector with negative integer array index (counts from the end of the array) | `$.bar[-1]`\n`[]` | non-empty, comma-separated sequence of selectors | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]`\n`..[]` | [descendant segment](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#descendant-segment): selects zero or more descendants of a node; contains one or more selectors, separated by commas | `$.foo..[\"bar\"]`\n`..name` | shorthand for `..['name']` | `$.foo..bar`\n`*` | [wildcard selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#name-selector): selects all children of a node | `$.foo[*]`, `$[*]`\n`.*` | shorthand for `.[*]` | `$.foo.*`, `$.*`\n`..*` | shorthand for `..[*]` | `$.foo..*`, `$..*`\n`[start:end]` | array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:5]`, same as `$.bar[2,3,4]`\n`[start:]` | array subset from _start_ to end of array | `$.bar[2:]`\n`[:n]` | the first _n_ array items | `$.bar[:4]`\n`[-n:]` | the last _n_ array items | `$.bar[-3:]`\n`[start:end:step]` | [array slice selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#slice) |\n`[?]` | [filter selector](): selects particular children using a logical expression | \n`@` | [current node identifier](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#filter-selector) (valid only within filter selectors) | `$.bar[?@.baz==42]`\n\n**References for JSONPath**\n- Current IETF draft: https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-20\n- Historic site: https://goessner.net/articles/JsonPath/\n- Node.js implementation: https://www.npmjs.com/package/jsonpath\n- Java implementation: https://github.com/json-path/JsonPath\n- Online evaluator: https://jsonpath.com/\n " + "@Core.Description": "[JSONPath](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html) expression", + "@Core.LongDescription": "Implementations SHOULD support at least the following subset of JSONPath:\n\nSyntax Element | Description | Examples\n---------------|-------------|--------\n`$` | [root identifier](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#root-identifier) | `$`\n`[]` | [child segment](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#child-segment) selects one child of a node; contains one [name selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#name-selector) (single- or double-quoted string using JSON escaping rules) or [index selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#index-selector) (non-negative decimal integer) | `$['foo']`, `$.foo[\"bar\"]`, `$.bar[0]`, `$.bar[42]`\n`.name` | shorthand for `['name']` | `$.foo`, `$.foo.bar`, `$.bar[42].baz`\n\nImplementations MAY support in addition:\n\nSyntax Element | Description | Examples\n---------------|-------------|--------\n`[]` | index selector with negative integer array index (counts from the end of the array) | `$.bar[-1]`\n`[]` | non-empty, comma-separated sequence of selectors | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]`\n`..[]` | [descendant segment](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#descendant-segment): selects zero or more descendants of a node; contains one or more selectors, separated by commas | `$.foo..[\"bar\"]`\n`..name` | shorthand for `..['name']` | `$.foo..bar`\n`*` | [wildcard selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#name-selector): selects all children of a node | `$.foo[*]`, `$[*]`\n`.*` | shorthand for `.[*]` | `$.foo.*`, `$.*`\n`..*` | shorthand for `..[*]` | `$.foo..*`, `$..*`\n`[start:end]` | array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:5]`, same as `$.bar[2,3,4]`\n`[start:]` | array subset from _start_ to end of array | `$.bar[2:]`\n`[:n]` | the first _n_ array items | `$.bar[:4]`\n`[-n:]` | the last _n_ array items | `$.bar[-3:]`\n`[start:end:step]` | [array slice selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#slice) |\n`[?]` | [filter selector](): selects particular children using a logical expression | \n`@` | [current node identifier](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#filter-selector) (valid only within filter selectors) | `$.bar[?@.baz==42]`\n\n**References for JSONPath**\n- Current IETF draft: https://datatracker.ietf.org/doc/draft-ietf-jsonpath-base/\n- Historic site: https://goessner.net/articles/JsonPath/\n- Node.js implementation: https://www.npmjs.com/package/jsonpath\n- Java implementation: https://github.com/json-path/JsonPath\n- Online evaluator: https://jsonpath.com/\n " } } } \ No newline at end of file diff --git a/vocabularies/Org.OData.JSON.V1.md b/vocabularies/Org.OData.JSON.V1.md index 8538e68a..d2c239fc 100644 --- a/vocabularies/Org.OData.JSON.V1.md +++ b/vocabularies/Org.OData.JSON.V1.md @@ -128,7 +128,7 @@ Textual data of media type `application/json` ## [Path](./Org.OData.JSON.V1.xml#L197:~:text= - + Implementations SHOULD support at least the following subset of JSONPath: @@ -225,7 +225,7 @@ Syntax Element | Description | Examples `@` | [current node identifier](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#filter-selector) (valid only within filter selectors) | `$.bar[?@.baz==42]` **References for JSONPath** -- Current IETF draft: https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-20 +- Current IETF draft: https://datatracker.ietf.org/doc/draft-ietf-jsonpath-base/ - Historic site: https://goessner.net/articles/JsonPath/ - Node.js implementation: https://www.npmjs.com/package/jsonpath - Java implementation: https://github.com/json-path/JsonPath From d9c8a6920f601aacf3baa1415f764523a53fb81f Mon Sep 17 00:00:00 2001 From: Ralf Handl Date: Fri, 22 Sep 2023 11:59:18 +0200 Subject: [PATCH 13/31] Additional JSONPath constructs are examples only, no restriction --- vocabularies/Org.OData.JSON.V1.json | 2 +- vocabularies/Org.OData.JSON.V1.md | 2 +- vocabularies/Org.OData.JSON.V1.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/vocabularies/Org.OData.JSON.V1.json b/vocabularies/Org.OData.JSON.V1.json index 745cc6b5..df8f82db 100644 --- a/vocabularies/Org.OData.JSON.V1.json +++ b/vocabularies/Org.OData.JSON.V1.json @@ -111,7 +111,7 @@ "$Kind": "TypeDefinition", "$UnderlyingType": "Edm.String", "@Core.Description": "[JSONPath](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html) expression", - "@Core.LongDescription": "Implementations SHOULD support at least the following subset of JSONPath:\n\nSyntax Element | Description | Examples\n---------------|-------------|--------\n`$` | [root identifier](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#root-identifier) | `$`\n`[]` | [child segment](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#child-segment) selects one child of a node; contains one [name selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#name-selector) (single- or double-quoted string using JSON escaping rules) or [index selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#index-selector) (non-negative decimal integer) | `$['foo']`, `$.foo[\"bar\"]`, `$.bar[0]`, `$.bar[42]`\n`.name` | shorthand for `['name']` | `$.foo`, `$.foo.bar`, `$.bar[42].baz`\n\nImplementations MAY support in addition:\n\nSyntax Element | Description | Examples\n---------------|-------------|--------\n`[]` | index selector with negative integer array index (counts from the end of the array) | `$.bar[-1]`\n`[]` | non-empty, comma-separated sequence of selectors | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]`\n`..[]` | [descendant segment](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#descendant-segment): selects zero or more descendants of a node; contains one or more selectors, separated by commas | `$.foo..[\"bar\"]`\n`..name` | shorthand for `..['name']` | `$.foo..bar`\n`*` | [wildcard selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#name-selector): selects all children of a node | `$.foo[*]`, `$[*]`\n`.*` | shorthand for `.[*]` | `$.foo.*`, `$.*`\n`..*` | shorthand for `..[*]` | `$.foo..*`, `$..*`\n`[start:end]` | array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:5]`, same as `$.bar[2,3,4]`\n`[start:]` | array subset from _start_ to end of array | `$.bar[2:]`\n`[:n]` | the first _n_ array items | `$.bar[:4]`\n`[-n:]` | the last _n_ array items | `$.bar[-3:]`\n`[start:end:step]` | [array slice selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#slice) |\n`[?]` | [filter selector](): selects particular children using a logical expression | \n`@` | [current node identifier](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#filter-selector) (valid only within filter selectors) | `$.bar[?@.baz==42]`\n\n**References for JSONPath**\n- Current IETF draft: https://datatracker.ietf.org/doc/draft-ietf-jsonpath-base/\n- Historic site: https://goessner.net/articles/JsonPath/\n- Node.js implementation: https://www.npmjs.com/package/jsonpath\n- Java implementation: https://github.com/json-path/JsonPath\n- Online evaluator: https://jsonpath.com/\n " + "@Core.LongDescription": "Implementations SHOULD support at least the following subset of JSONPath:\n\nSyntax Element | Description | Examples\n---------------|-------------|--------\n`$` | [root identifier](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#root-identifier) | `$`\n`[]` | [child segment](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#child-segment) selects one child of a node; contains one [name selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#name-selector) (single- or double-quoted string using JSON escaping rules) or [index selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#index-selector) (non-negative decimal integer) | `$['foo']`, `$.foo[\"bar\"]`, `$.bar[0]`, `$.bar[42]`\n`.name` | shorthand for `['name']` | `$.foo`, `$.foo.bar`, `$.bar[42].baz`\n\nImplementations MAY in addition support other JSONPath constructs, for example:\n\nSyntax Element | Description | Examples\n---------------|-------------|--------\n`[]` | index selector with negative integer array index (counts from the end of the array) | `$.bar[-1]`\n`[]` | non-empty, comma-separated sequence of selectors | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]`\n`..[]` | [descendant segment](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#descendant-segment): selects zero or more descendants of a node; contains one or more selectors, separated by commas | `$.foo..[\"bar\"]`\n`..name` | shorthand for `..['name']` | `$.foo..bar`\n`*` | [wildcard selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#name-selector): selects all children of a node | `$.foo[*]`, `$[*]`\n`.*` | shorthand for `.[*]` | `$.foo.*`, `$.*`\n`..*` | shorthand for `..[*]` | `$.foo..*`, `$..*`\n`[start:end]` | array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:5]`, same as `$.bar[2,3,4]`\n`[start:]` | array subset from _start_ to end of array | `$.bar[2:]`\n`[:n]` | the first _n_ array items | `$.bar[:4]`\n`[-n:]` | the last _n_ array items | `$.bar[-3:]`\n`[start:end:step]` | [array slice selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#slice) |\n`[?]` | [filter selector](): selects particular children using a logical expression | \n`@` | [current node identifier](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#filter-selector) (valid only within filter selectors) | `$.bar[?@.baz==42]`\n\n**References for JSONPath**\n- Current IETF draft: https://datatracker.ietf.org/doc/draft-ietf-jsonpath-base/\n- Historic site: https://goessner.net/articles/JsonPath/\n- Node.js implementation: https://www.npmjs.com/package/jsonpath\n- Java implementation: https://github.com/json-path/JsonPath\n- Online evaluator: https://jsonpath.com/\n " } } } \ No newline at end of file diff --git a/vocabularies/Org.OData.JSON.V1.md b/vocabularies/Org.OData.JSON.V1.md index d2c239fc..84a1002a 100644 --- a/vocabularies/Org.OData.JSON.V1.md +++ b/vocabularies/Org.OData.JSON.V1.md @@ -138,7 +138,7 @@ Syntax Element | Description | Examples `[]` | [child segment](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#child-segment) selects one child of a node; contains one [name selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#name-selector) (single- or double-quoted string using JSON escaping rules) or [index selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#index-selector) (non-negative decimal integer) | `$['foo']`, `$.foo["bar"]`, `$.bar[0]`, `$.bar[42]` `.name` | shorthand for `['name']` | `$.foo`, `$.foo.bar`, `$.bar[42].baz` -Implementations MAY support in addition: +Implementations MAY in addition support other JSONPath constructs, for example: Syntax Element | Description | Examples ---------------|-------------|-------- diff --git a/vocabularies/Org.OData.JSON.V1.xml b/vocabularies/Org.OData.JSON.V1.xml index 799958fe..f77a534b 100644 --- a/vocabularies/Org.OData.JSON.V1.xml +++ b/vocabularies/Org.OData.JSON.V1.xml @@ -205,7 +205,7 @@ Syntax Element | Description | Examples `[<selector>]` | [child segment](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#child-segment) selects one child of a node; contains one [name selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#name-selector) (single- or double-quoted string using JSON escaping rules) or [index selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#index-selector) (non-negative decimal integer) | `$['foo']`, `$.foo["bar"]`, `$.bar[0]`, `$.bar[42]` `.name` | shorthand for `['name']` | `$.foo`, `$.foo.bar`, `$.bar[42].baz` -Implementations MAY support in addition: +Implementations MAY in addition support other JSONPath constructs, for example: Syntax Element | Description | Examples ---------------|-------------|-------- From 6f9faac15f8ea7fe2fa1bc0cb10650691c70df3c Mon Sep 17 00:00:00 2001 From: Ralf Handl Date: Thu, 29 Feb 2024 14:38:09 +0100 Subject: [PATCH 14/31] Typo --- vocabularies/Org.OData.JSON.V1.json | 2 +- vocabularies/Org.OData.JSON.V1.md | 2 +- vocabularies/Org.OData.JSON.V1.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/vocabularies/Org.OData.JSON.V1.json b/vocabularies/Org.OData.JSON.V1.json index df8f82db..241ef396 100644 --- a/vocabularies/Org.OData.JSON.V1.json +++ b/vocabularies/Org.OData.JSON.V1.json @@ -13,7 +13,7 @@ "Org.OData.JSON.V1": { "$Alias": "JSON", "@Core.Description": "Terms, types, and functions for JSON streams", - "@Core.LongDescription": "OData [stream properties](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ManagingStreamProperties) allow embedding data of arbitrary media types,\nand the OData JSON format allows [direct embedding of JSON data](https://docs.oasis-open.org/odata/odata-json-format/v4.01/odata-json-format-v4.01.html#sec_StreamProperty) in request and response payloads.\n \nThis vocabulary defines a convenince [type for JSON streams](#JSON) streams as well as a term for referencing a [JSON Schema](#Schema) describing the structure of the JSON stream. \n\nIn addition it defines two functions for [querying](#query) JSON streams and using a [primitive value](#value) extracted from a JSON stream in common expressions, for example in `$filter`, `$orderby`, or `$compute`.\n\n**Example**\n\nThe `Employees` entity set has a JSON stream property `resume`:\n```json\n\"container\": {\n \"$Kind\": \"EntityContainer\",\n \"Employees\": { \"$Collection\": true, \"$Type\": \"this.Employee\" }\n},\n\"Employee\": {\n \"$Kind\": \"EntityType\",\n \"$Key\": [\"empid\"],\n \"empid\": { \"$Type\": \"Edm.Int32\" },\n \"resume\": { \"$Type\": \"JSON.JSON\", \"$Nullable\": true }\n}\n```\n\nOne of its entities has a `resume` value of\n```json\n{ \n \"ssn\": \"1234\", \n \"lastname\": \"Doe\", \n \"address\": {\n \"zipcode\": \"10022\", \n \"street\": \"ABC st\"\n },\n \"experience\": \"excellent\"\n}\n```\n\nThis allows to filter and sort by values in that resume, and extract parts of the resume as a dynamic JSON stream property\n```http\nGET http://www.example.com/mycompany/Employees\n ?$filter=resume/JSON.value('$.lastname') eq 'Doe'\n &$orderby=resume/JSON.value('$.experience')\n &$compute=resume/JSON.query('$.address') as address\n &$expand=address\n```\nreceiving\n```json\n{ \n \"@odata.context\": \"$metadata#Employees\", \n \"value\": [ \n {\n \"empid\": 4711,\n \"address\": {\n \"zipcode\": \"10022\", \n \"street\": \"ABC st\"\n }\n },\n ...\n ]\n}\n```\n ", + "@Core.LongDescription": "OData [stream properties](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ManagingStreamProperties) allow embedding data of arbitrary media types,\nand the OData JSON format allows [direct embedding of JSON data](https://docs.oasis-open.org/odata/odata-json-format/v4.01/odata-json-format-v4.01.html#sec_StreamProperty) in request and response payloads.\n \nThis vocabulary defines a convenience [type for JSON streams](#JSON) streams as well as a term for referencing a [JSON Schema](#Schema) describing the structure of the JSON stream. \n\nIn addition it defines two functions for [querying](#query) JSON streams and using a [primitive value](#value) extracted from a JSON stream in common expressions, for example in `$filter`, `$orderby`, or `$compute`.\n\n**Example**\n\nThe `Employees` entity set has a JSON stream property `resume`:\n```json\n\"container\": {\n \"$Kind\": \"EntityContainer\",\n \"Employees\": { \"$Collection\": true, \"$Type\": \"this.Employee\" }\n},\n\"Employee\": {\n \"$Kind\": \"EntityType\",\n \"$Key\": [\"empid\"],\n \"empid\": { \"$Type\": \"Edm.Int32\" },\n \"resume\": { \"$Type\": \"JSON.JSON\", \"$Nullable\": true }\n}\n```\n\nOne of its entities has a `resume` value of\n```json\n{ \n \"ssn\": \"1234\", \n \"lastname\": \"Doe\", \n \"address\": {\n \"zipcode\": \"10022\", \n \"street\": \"ABC st\"\n },\n \"experience\": \"excellent\"\n}\n```\n\nThis allows to filter and sort by values in that resume, and extract parts of the resume as a dynamic JSON stream property\n```http\nGET http://www.example.com/mycompany/Employees\n ?$filter=resume/JSON.value('$.lastname') eq 'Doe'\n &$orderby=resume/JSON.value('$.experience')\n &$compute=resume/JSON.query('$.address') as address\n &$expand=address\n```\nreceiving\n```json\n{ \n \"@odata.context\": \"$metadata#Employees\", \n \"value\": [ \n {\n \"empid\": 4711,\n \"address\": {\n \"zipcode\": \"10022\", \n \"street\": \"ABC st\"\n }\n },\n ...\n ]\n}\n```\n ", "@Core.Links": [ { "rel": "alternate", diff --git a/vocabularies/Org.OData.JSON.V1.md b/vocabularies/Org.OData.JSON.V1.md index 84a1002a..fe3cfcf9 100644 --- a/vocabularies/Org.OData.JSON.V1.md +++ b/vocabularies/Org.OData.JSON.V1.md @@ -6,7 +6,7 @@ Terms, types, and functions for JSON streams OData [stream properties](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ManagingStreamProperties) allow embedding data of arbitrary media types, and the OData JSON format allows [direct embedding of JSON data](https://docs.oasis-open.org/odata/odata-json-format/v4.01/odata-json-format-v4.01.html#sec_StreamProperty) in request and response payloads. -This vocabulary defines a convenince [type for JSON streams](#JSON) streams as well as a term for referencing a [JSON Schema](#Schema) describing the structure of the JSON stream. +This vocabulary defines a convenience [type for JSON streams](#JSON) streams as well as a term for referencing a [JSON Schema](#Schema) describing the structure of the JSON stream. In addition it defines two functions for [querying](#query) JSON streams and using a [primitive value](#value) extracted from a JSON stream in common expressions, for example in `$filter`, `$orderby`, or `$compute`. diff --git a/vocabularies/Org.OData.JSON.V1.xml b/vocabularies/Org.OData.JSON.V1.xml index f77a534b..5df7b959 100644 --- a/vocabularies/Org.OData.JSON.V1.xml +++ b/vocabularies/Org.OData.JSON.V1.xml @@ -51,7 +51,7 @@ OData [stream properties](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ManagingStreamProperties) allow embedding data of arbitrary media types, and the OData JSON format allows [direct embedding of JSON data](https://docs.oasis-open.org/odata/odata-json-format/v4.01/odata-json-format-v4.01.html#sec_StreamProperty) in request and response payloads. -This vocabulary defines a convenince [type for JSON streams](#JSON) streams as well as a term for referencing a [JSON Schema](#Schema) describing the structure of the JSON stream. +This vocabulary defines a convenience [type for JSON streams](#JSON) streams as well as a term for referencing a [JSON Schema](#Schema) describing the structure of the JSON stream. In addition it defines two functions for [querying](#query) JSON streams and using a [primitive value](#value) extracted from a JSON stream in common expressions, for example in `$filter`, `$orderby`, or `$compute`. From 873715f5ae77ebfe3ba901f8b27a60cb70ac4f72 Mon Sep 17 00:00:00 2001 From: Ralf Handl Date: Thu, 29 Feb 2024 15:09:38 +0100 Subject: [PATCH 15/31] Typo --- vocabularies/Org.OData.JSON.V1.json | 2 +- vocabularies/Org.OData.JSON.V1.md | 2 +- vocabularies/Org.OData.JSON.V1.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/vocabularies/Org.OData.JSON.V1.json b/vocabularies/Org.OData.JSON.V1.json index 241ef396..e2f20f05 100644 --- a/vocabularies/Org.OData.JSON.V1.json +++ b/vocabularies/Org.OData.JSON.V1.json @@ -111,7 +111,7 @@ "$Kind": "TypeDefinition", "$UnderlyingType": "Edm.String", "@Core.Description": "[JSONPath](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html) expression", - "@Core.LongDescription": "Implementations SHOULD support at least the following subset of JSONPath:\n\nSyntax Element | Description | Examples\n---------------|-------------|--------\n`$` | [root identifier](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#root-identifier) | `$`\n`[]` | [child segment](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#child-segment) selects one child of a node; contains one [name selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#name-selector) (single- or double-quoted string using JSON escaping rules) or [index selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#index-selector) (non-negative decimal integer) | `$['foo']`, `$.foo[\"bar\"]`, `$.bar[0]`, `$.bar[42]`\n`.name` | shorthand for `['name']` | `$.foo`, `$.foo.bar`, `$.bar[42].baz`\n\nImplementations MAY in addition support other JSONPath constructs, for example:\n\nSyntax Element | Description | Examples\n---------------|-------------|--------\n`[]` | index selector with negative integer array index (counts from the end of the array) | `$.bar[-1]`\n`[]` | non-empty, comma-separated sequence of selectors | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]`\n`..[]` | [descendant segment](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#descendant-segment): selects zero or more descendants of a node; contains one or more selectors, separated by commas | `$.foo..[\"bar\"]`\n`..name` | shorthand for `..['name']` | `$.foo..bar`\n`*` | [wildcard selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#name-selector): selects all children of a node | `$.foo[*]`, `$[*]`\n`.*` | shorthand for `.[*]` | `$.foo.*`, `$.*`\n`..*` | shorthand for `..[*]` | `$.foo..*`, `$..*`\n`[start:end]` | array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:5]`, same as `$.bar[2,3,4]`\n`[start:]` | array subset from _start_ to end of array | `$.bar[2:]`\n`[:n]` | the first _n_ array items | `$.bar[:4]`\n`[-n:]` | the last _n_ array items | `$.bar[-3:]`\n`[start:end:step]` | [array slice selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#slice) |\n`[?]` | [filter selector](): selects particular children using a logical expression | \n`@` | [current node identifier](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#filter-selector) (valid only within filter selectors) | `$.bar[?@.baz==42]`\n\n**References for JSONPath**\n- Current IETF draft: https://datatracker.ietf.org/doc/draft-ietf-jsonpath-base/\n- Historic site: https://goessner.net/articles/JsonPath/\n- Node.js implementation: https://www.npmjs.com/package/jsonpath\n- Java implementation: https://github.com/json-path/JsonPath\n- Online evaluator: https://jsonpath.com/\n " + "@Core.LongDescription": "Implementations SHOULD support at least the following subset of JSONPath:\n\nSyntax Element | Description | Examples\n---------------|-------------|--------\n`$` | [root identifier](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#root-identifier) | `$`\n`[]` | [child segment](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#child-segment) selects one child of a node; contains one [name selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#name-selector) (single- or double-quoted string using JSON escaping rules) or [index selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#index-selector) (non-negative decimal integer) | `$['foo']`, `$.foo[\"bar\"]`, `$.bar[0]`, `$.bar[42]`\n`.name` | shorthand for `['name']` | `$.foo`, `$.foo.bar`, `$.bar[42].baz`\n\nImplementations MAY in addition support other JSONPath constructs, for example:\n\nSyntax Element | Description | Examples\n---------------|-------------|--------\n`[]` | index selector with negative integer array index (counts from the end of the array) | `$.bar[-1]`\n`[]` | non-empty, comma-separated sequence of selectors | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]`\n`..[]` | [descendant segment](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#descendant-segment): selects zero or more descendants of a node; contains one or more selectors, separated by commas | `$.foo..[\"bar\"]`\n`..name` | shorthand for `..['name']` | `$.foo..bar`\n`*` | [wildcard selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#name-selector): selects all children of a node | `$.foo[*]`, `$[*]`\n`.*` | shorthand for `[*]` | `$.foo.*`, `$.*`\n`..*` | shorthand for `..[*]` | `$.foo..*`, `$..*`\n`[start:end]` | array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:5]`, same as `$.bar[2,3,4]`\n`[start:]` | array subset from _start_ to end of array | `$.bar[2:]`\n`[:n]` | the first _n_ array items | `$.bar[:4]`\n`[-n:]` | the last _n_ array items | `$.bar[-3:]`\n`[start:end:step]` | [array slice selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#slice) |\n`[?]` | [filter selector](): selects particular children using a logical expression | \n`@` | [current node identifier](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#filter-selector) (valid only within filter selectors) | `$.bar[?@.baz==42]`\n\n**References for JSONPath**\n- Current IETF draft: https://datatracker.ietf.org/doc/draft-ietf-jsonpath-base/\n- Historic site: https://goessner.net/articles/JsonPath/\n- Node.js implementation: https://www.npmjs.com/package/jsonpath\n- Java implementation: https://github.com/json-path/JsonPath\n- Online evaluator: https://jsonpath.com/\n " } } } \ No newline at end of file diff --git a/vocabularies/Org.OData.JSON.V1.md b/vocabularies/Org.OData.JSON.V1.md index fe3cfcf9..c5e76c8c 100644 --- a/vocabularies/Org.OData.JSON.V1.md +++ b/vocabularies/Org.OData.JSON.V1.md @@ -147,7 +147,7 @@ Syntax Element | Description | Examples `..[]` | [descendant segment](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#descendant-segment): selects zero or more descendants of a node; contains one or more selectors, separated by commas | `$.foo..["bar"]` `..name` | shorthand for `..['name']` | `$.foo..bar` `*` | [wildcard selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#name-selector): selects all children of a node | `$.foo[*]`, `$[*]` -`.*` | shorthand for `.[*]` | `$.foo.*`, `$.*` +`.*` | shorthand for `[*]` | `$.foo.*`, `$.*` `..*` | shorthand for `..[*]` | `$.foo..*`, `$..*` `[start:end]` | array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:5]`, same as `$.bar[2,3,4]` `[start:]` | array subset from _start_ to end of array | `$.bar[2:]` diff --git a/vocabularies/Org.OData.JSON.V1.xml b/vocabularies/Org.OData.JSON.V1.xml index 5df7b959..436e36a4 100644 --- a/vocabularies/Org.OData.JSON.V1.xml +++ b/vocabularies/Org.OData.JSON.V1.xml @@ -214,7 +214,7 @@ Syntax Element | Description | Examples `..[<selectors>]` | [descendant segment](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#descendant-segment): selects zero or more descendants of a node; contains one or more selectors, separated by commas | `$.foo..["bar"]` `..name` | shorthand for `..['name']` | `$.foo..bar` `*` | [wildcard selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#name-selector): selects all children of a node | `$.foo[*]`, `$[*]` -`.*` | shorthand for `.[*]` | `$.foo.*`, `$.*` +`.*` | shorthand for `[*]` | `$.foo.*`, `$.*` `..*` | shorthand for `..[*]` | `$.foo..*`, `$..*` `[start:end]` | array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:5]`, same as `$.bar[2,3,4]` `[start:]` | array subset from _start_ to end of array | `$.bar[2:]` From bb8577ff112e3cf1905581f49ceef51f450ca532 Mon Sep 17 00:00:00 2001 From: Ralf Handl Date: Thu, 29 Feb 2024 15:15:40 +0100 Subject: [PATCH 16/31] JSONPath is now an RFC --- vocabularies/Org.OData.JSON.V1.json | 2 +- vocabularies/Org.OData.JSON.V1.md | 2 +- vocabularies/Org.OData.JSON.V1.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/vocabularies/Org.OData.JSON.V1.json b/vocabularies/Org.OData.JSON.V1.json index e2f20f05..ce6368f9 100644 --- a/vocabularies/Org.OData.JSON.V1.json +++ b/vocabularies/Org.OData.JSON.V1.json @@ -111,7 +111,7 @@ "$Kind": "TypeDefinition", "$UnderlyingType": "Edm.String", "@Core.Description": "[JSONPath](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html) expression", - "@Core.LongDescription": "Implementations SHOULD support at least the following subset of JSONPath:\n\nSyntax Element | Description | Examples\n---------------|-------------|--------\n`$` | [root identifier](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#root-identifier) | `$`\n`[]` | [child segment](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#child-segment) selects one child of a node; contains one [name selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#name-selector) (single- or double-quoted string using JSON escaping rules) or [index selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#index-selector) (non-negative decimal integer) | `$['foo']`, `$.foo[\"bar\"]`, `$.bar[0]`, `$.bar[42]`\n`.name` | shorthand for `['name']` | `$.foo`, `$.foo.bar`, `$.bar[42].baz`\n\nImplementations MAY in addition support other JSONPath constructs, for example:\n\nSyntax Element | Description | Examples\n---------------|-------------|--------\n`[]` | index selector with negative integer array index (counts from the end of the array) | `$.bar[-1]`\n`[]` | non-empty, comma-separated sequence of selectors | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]`\n`..[]` | [descendant segment](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#descendant-segment): selects zero or more descendants of a node; contains one or more selectors, separated by commas | `$.foo..[\"bar\"]`\n`..name` | shorthand for `..['name']` | `$.foo..bar`\n`*` | [wildcard selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#name-selector): selects all children of a node | `$.foo[*]`, `$[*]`\n`.*` | shorthand for `[*]` | `$.foo.*`, `$.*`\n`..*` | shorthand for `..[*]` | `$.foo..*`, `$..*`\n`[start:end]` | array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:5]`, same as `$.bar[2,3,4]`\n`[start:]` | array subset from _start_ to end of array | `$.bar[2:]`\n`[:n]` | the first _n_ array items | `$.bar[:4]`\n`[-n:]` | the last _n_ array items | `$.bar[-3:]`\n`[start:end:step]` | [array slice selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#slice) |\n`[?]` | [filter selector](): selects particular children using a logical expression | \n`@` | [current node identifier](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#filter-selector) (valid only within filter selectors) | `$.bar[?@.baz==42]`\n\n**References for JSONPath**\n- Current IETF draft: https://datatracker.ietf.org/doc/draft-ietf-jsonpath-base/\n- Historic site: https://goessner.net/articles/JsonPath/\n- Node.js implementation: https://www.npmjs.com/package/jsonpath\n- Java implementation: https://github.com/json-path/JsonPath\n- Online evaluator: https://jsonpath.com/\n " + "@Core.LongDescription": "Implementations SHOULD support at least the following subset of JSONPath:\n\nSyntax Element | Description | Examples\n---------------|-------------|--------\n`$` | [root identifier](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#root-identifier) | `$`\n`[]` | [child segment](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#child-segment) selects one child of a node; contains one [name selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#name-selector) (single- or double-quoted string using JSON escaping rules) or [index selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#index-selector) (non-negative decimal integer) | `$['foo']`, `$.foo[\"bar\"]`, `$.bar[0]`, `$.bar[42]`\n`.name` | shorthand for `['name']` | `$.foo`, `$.foo.bar`, `$.bar[42].baz`\n\nImplementations MAY in addition support other JSONPath constructs, for example:\n\nSyntax Element | Description | Examples\n---------------|-------------|--------\n`[]` | index selector with negative integer array index (counts from the end of the array) | `$.bar[-1]`\n`[]` | non-empty, comma-separated sequence of selectors | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]`\n`..[]` | [descendant segment](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#descendant-segment): selects zero or more descendants of a node; contains one or more selectors, separated by commas | `$.foo..[\"bar\"]`\n`..name` | shorthand for `..['name']` | `$.foo..bar`\n`*` | [wildcard selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#name-selector): selects all children of a node | `$.foo[*]`, `$[*]`\n`.*` | shorthand for `[*]` | `$.foo.*`, `$.*`\n`..*` | shorthand for `..[*]` | `$.foo..*`, `$..*`\n`[start:end]` | array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:5]`, same as `$.bar[2,3,4]`\n`[start:]` | array subset from _start_ to end of array | `$.bar[2:]`\n`[:n]` | the first _n_ array items | `$.bar[:4]`\n`[-n:]` | the last _n_ array items | `$.bar[-3:]`\n`[start:end:step]` | [array slice selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#slice) |\n`[?]` | [filter selector](): selects particular children using a logical expression | \n`@` | [current node identifier](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#filter-selector) (valid only within filter selectors) | `$.bar[?@.baz==42]`\n\n**References for JSONPath**\n- RFC 9535: https://datatracker.ietf.org/doc/html/rfc9535\n- Historic site: https://goessner.net/articles/JsonPath/\n- Node.js implementation: https://www.npmjs.com/package/jsonpath\n- Java implementation: https://github.com/json-path/JsonPath\n- Online evaluator: https://jsonpath.com/\n " } } } \ No newline at end of file diff --git a/vocabularies/Org.OData.JSON.V1.md b/vocabularies/Org.OData.JSON.V1.md index c5e76c8c..b0f6eb93 100644 --- a/vocabularies/Org.OData.JSON.V1.md +++ b/vocabularies/Org.OData.JSON.V1.md @@ -158,7 +158,7 @@ Syntax Element | Description | Examples `@` | [current node identifier](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#filter-selector) (valid only within filter selectors) | `$.bar[?@.baz==42]` **References for JSONPath** -- Current IETF draft: https://datatracker.ietf.org/doc/draft-ietf-jsonpath-base/ +- RFC 9535: https://datatracker.ietf.org/doc/html/rfc9535 - Historic site: https://goessner.net/articles/JsonPath/ - Node.js implementation: https://www.npmjs.com/package/jsonpath - Java implementation: https://github.com/json-path/JsonPath diff --git a/vocabularies/Org.OData.JSON.V1.xml b/vocabularies/Org.OData.JSON.V1.xml index 436e36a4..bf079011 100644 --- a/vocabularies/Org.OData.JSON.V1.xml +++ b/vocabularies/Org.OData.JSON.V1.xml @@ -225,7 +225,7 @@ Syntax Element | Description | Examples `@` | [current node identifier](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#filter-selector) (valid only within filter selectors) | `$.bar[?@.baz==42]` **References for JSONPath** -- Current IETF draft: https://datatracker.ietf.org/doc/draft-ietf-jsonpath-base/ +- RFC 9535: https://datatracker.ietf.org/doc/html/rfc9535 - Historic site: https://goessner.net/articles/JsonPath/ - Node.js implementation: https://www.npmjs.com/package/jsonpath - Java implementation: https://github.com/json-path/JsonPath From 5b389f24dcfb81fe4fc22182b7bc0b70bfcc98bd Mon Sep 17 00:00:00 2001 From: Ralf Handl Date: Thu, 29 Feb 2024 15:27:45 +0100 Subject: [PATCH 17/31] Update links --- vocabularies/Org.OData.JSON.V1.json | 4 ++-- vocabularies/Org.OData.JSON.V1.md | 18 +++++++++--------- vocabularies/Org.OData.JSON.V1.xml | 18 +++++++++--------- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/vocabularies/Org.OData.JSON.V1.json b/vocabularies/Org.OData.JSON.V1.json index ce6368f9..6f673ac3 100644 --- a/vocabularies/Org.OData.JSON.V1.json +++ b/vocabularies/Org.OData.JSON.V1.json @@ -110,8 +110,8 @@ "Path": { "$Kind": "TypeDefinition", "$UnderlyingType": "Edm.String", - "@Core.Description": "[JSONPath](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html) expression", - "@Core.LongDescription": "Implementations SHOULD support at least the following subset of JSONPath:\n\nSyntax Element | Description | Examples\n---------------|-------------|--------\n`$` | [root identifier](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#root-identifier) | `$`\n`[]` | [child segment](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#child-segment) selects one child of a node; contains one [name selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#name-selector) (single- or double-quoted string using JSON escaping rules) or [index selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#index-selector) (non-negative decimal integer) | `$['foo']`, `$.foo[\"bar\"]`, `$.bar[0]`, `$.bar[42]`\n`.name` | shorthand for `['name']` | `$.foo`, `$.foo.bar`, `$.bar[42].baz`\n\nImplementations MAY in addition support other JSONPath constructs, for example:\n\nSyntax Element | Description | Examples\n---------------|-------------|--------\n`[]` | index selector with negative integer array index (counts from the end of the array) | `$.bar[-1]`\n`[]` | non-empty, comma-separated sequence of selectors | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]`\n`..[]` | [descendant segment](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#descendant-segment): selects zero or more descendants of a node; contains one or more selectors, separated by commas | `$.foo..[\"bar\"]`\n`..name` | shorthand for `..['name']` | `$.foo..bar`\n`*` | [wildcard selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#name-selector): selects all children of a node | `$.foo[*]`, `$[*]`\n`.*` | shorthand for `[*]` | `$.foo.*`, `$.*`\n`..*` | shorthand for `..[*]` | `$.foo..*`, `$..*`\n`[start:end]` | array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:5]`, same as `$.bar[2,3,4]`\n`[start:]` | array subset from _start_ to end of array | `$.bar[2:]`\n`[:n]` | the first _n_ array items | `$.bar[:4]`\n`[-n:]` | the last _n_ array items | `$.bar[-3:]`\n`[start:end:step]` | [array slice selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#slice) |\n`[?]` | [filter selector](): selects particular children using a logical expression | \n`@` | [current node identifier](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#filter-selector) (valid only within filter selectors) | `$.bar[?@.baz==42]`\n\n**References for JSONPath**\n- RFC 9535: https://datatracker.ietf.org/doc/html/rfc9535\n- Historic site: https://goessner.net/articles/JsonPath/\n- Node.js implementation: https://www.npmjs.com/package/jsonpath\n- Java implementation: https://github.com/json-path/JsonPath\n- Online evaluator: https://jsonpath.com/\n " + "@Core.Description": "[JSONPath](https://datatracker.ietf.org/doc/html/rfc9535) expression", + "@Core.LongDescription": "Implementations SHOULD support at least the following subset of JSONPath:\n\nSyntax Element | Description | Examples\n---------------|-------------|--------\n`$` | [root identifier](https://datatracker.ietf.org/doc/html/rfc9535#root-identifier) | `$`\n`[]` | [child segment](https://datatracker.ietf.org/doc/html/rfc9535#child-segment) selects one child of a node; contains one [name selector](https://datatracker.ietf.org/doc/html/rfc9535#name-selector) (single- or double-quoted string using JSON escaping rules) or [index selector](https://datatracker.ietf.org/doc/html/rfc9535#index-selector) (non-negative decimal integer) | `$['foo']`, `$.foo[\"bar\"]`, `$.bar[0]`, `$.bar[42]`\n`.name` | shorthand for `['name']` | `$.foo`, `$.foo.bar`, `$.bar[42].baz`\n\nImplementations MAY in addition support other JSONPath constructs, for example:\n\nSyntax Element | Description | Examples\n---------------|-------------|--------\n`[]` | index selector with negative integer array index (counts from the end of the array) | `$.bar[-1]`\n`[]` | non-empty, comma-separated sequence of selectors | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]`\n`..[]` | [descendant segment](https://datatracker.ietf.org/doc/html/rfc9535#descendant-segment): selects zero or more descendants of a node; contains one or more selectors, separated by commas | `$.foo..[\"bar\"]`\n`..name` | shorthand for `..['name']` | `$.foo..bar`\n`*` | [wildcard selector](https://datatracker.ietf.org/doc/html/rfc9535#name-selector): selects all children of a node | `$.foo[*]`, `$[*]`\n`.*` | shorthand for `.[*]` | `$.foo.*`, `$.*`\n`..*` | shorthand for `..[*]` | `$.foo..*`, `$..*`\n`[start:end]` | array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:5]`, same as `$.bar[2,3,4]`\n`[start:]` | array subset from _start_ to end of array | `$.bar[2:]`\n`[:n]` | the first _n_ array items | `$.bar[:4]`\n`[-n:]` | the last _n_ array items | `$.bar[-3:]`\n`[start:end:step]` | [array slice selector](https://datatracker.ietf.org/doc/html/rfc9535#slice) |\n`[?]` | [filter selector](https://datatracker.ietf.org/doc/html/rfc9535#filter-selector): selects particular children using a logical expression | \n`@` | [current node identifier](https://datatracker.ietf.org/doc/html/rfc9535#filter-selector) (valid only within filter selectors) | `$.bar[?@.baz==42]`\n\n**References for JSONPath**\n- RFC 9535: https://datatracker.ietf.org/doc/html/rfc9535\n- Historic site: https://goessner.net/articles/JsonPath/\n- Node.js implementation: https://www.npmjs.com/package/jsonpath\n- Java implementation: https://github.com/json-path/JsonPath\n- Online evaluator: https://jsonpath.com/\n " } } } \ No newline at end of file diff --git a/vocabularies/Org.OData.JSON.V1.md b/vocabularies/Org.OData.JSON.V1.md index b0f6eb93..15e9be54 100644 --- a/vocabularies/Org.OData.JSON.V1.md +++ b/vocabularies/Org.OData.JSON.V1.md @@ -128,14 +128,14 @@ Textual data of media type `application/json` ## [Path](./Org.OData.JSON.V1.xml#L197:~:text=]` | [child segment](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#child-segment) selects one child of a node; contains one [name selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#name-selector) (single- or double-quoted string using JSON escaping rules) or [index selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#index-selector) (non-negative decimal integer) | `$['foo']`, `$.foo["bar"]`, `$.bar[0]`, `$.bar[42]` +`$` | [root identifier](https://datatracker.ietf.org/doc/html/rfc9535#root-identifier) | `$` +`[]` | [child segment](https://datatracker.ietf.org/doc/html/rfc9535#child-segment) selects one child of a node; contains one [name selector](https://datatracker.ietf.org/doc/html/rfc9535#name-selector) (single- or double-quoted string using JSON escaping rules) or [index selector](https://datatracker.ietf.org/doc/html/rfc9535#index-selector) (non-negative decimal integer) | `$['foo']`, `$.foo["bar"]`, `$.bar[0]`, `$.bar[42]` `.name` | shorthand for `['name']` | `$.foo`, `$.foo.bar`, `$.bar[42].baz` Implementations MAY in addition support other JSONPath constructs, for example: @@ -144,18 +144,18 @@ Syntax Element | Description | Examples ---------------|-------------|-------- `[]` | index selector with negative integer array index (counts from the end of the array) | `$.bar[-1]` `[]` | non-empty, comma-separated sequence of selectors | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]` -`..[]` | [descendant segment](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#descendant-segment): selects zero or more descendants of a node; contains one or more selectors, separated by commas | `$.foo..["bar"]` +`..[]` | [descendant segment](https://datatracker.ietf.org/doc/html/rfc9535#descendant-segment): selects zero or more descendants of a node; contains one or more selectors, separated by commas | `$.foo..["bar"]` `..name` | shorthand for `..['name']` | `$.foo..bar` -`*` | [wildcard selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#name-selector): selects all children of a node | `$.foo[*]`, `$[*]` -`.*` | shorthand for `[*]` | `$.foo.*`, `$.*` +`*` | [wildcard selector](https://datatracker.ietf.org/doc/html/rfc9535#name-selector): selects all children of a node | `$.foo[*]`, `$[*]` +`.*` | shorthand for `.[*]` | `$.foo.*`, `$.*` `..*` | shorthand for `..[*]` | `$.foo..*`, `$..*` `[start:end]` | array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:5]`, same as `$.bar[2,3,4]` `[start:]` | array subset from _start_ to end of array | `$.bar[2:]` `[:n]` | the first _n_ array items | `$.bar[:4]` `[-n:]` | the last _n_ array items | `$.bar[-3:]` -`[start:end:step]` | [array slice selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#slice) | -`[?]` | [filter selector](): selects particular children using a logical expression | -`@` | [current node identifier](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#filter-selector) (valid only within filter selectors) | `$.bar[?@.baz==42]` +`[start:end:step]` | [array slice selector](https://datatracker.ietf.org/doc/html/rfc9535#slice) | +`[?]` | [filter selector](https://datatracker.ietf.org/doc/html/rfc9535#filter-selector): selects particular children using a logical expression | +`@` | [current node identifier](https://datatracker.ietf.org/doc/html/rfc9535#filter-selector) (valid only within filter selectors) | `$.bar[?@.baz==42]` **References for JSONPath** - RFC 9535: https://datatracker.ietf.org/doc/html/rfc9535 diff --git a/vocabularies/Org.OData.JSON.V1.xml b/vocabularies/Org.OData.JSON.V1.xml index bf079011..51227c85 100644 --- a/vocabularies/Org.OData.JSON.V1.xml +++ b/vocabularies/Org.OData.JSON.V1.xml @@ -195,14 +195,14 @@ If a single non-null scalar JSON value is identified by `path` within `input`, t - + Implementations SHOULD support at least the following subset of JSONPath: Syntax Element | Description | Examples ---------------|-------------|-------- -`$` | [root identifier](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#root-identifier) | `$` -`[<selector>]` | [child segment](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#child-segment) selects one child of a node; contains one [name selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#name-selector) (single- or double-quoted string using JSON escaping rules) or [index selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#index-selector) (non-negative decimal integer) | `$['foo']`, `$.foo["bar"]`, `$.bar[0]`, `$.bar[42]` +`$` | [root identifier](https://datatracker.ietf.org/doc/html/rfc9535#root-identifier) | `$` +`[<selector>]` | [child segment](https://datatracker.ietf.org/doc/html/rfc9535#child-segment) selects one child of a node; contains one [name selector](https://datatracker.ietf.org/doc/html/rfc9535#name-selector) (single- or double-quoted string using JSON escaping rules) or [index selector](https://datatracker.ietf.org/doc/html/rfc9535#index-selector) (non-negative decimal integer) | `$['foo']`, `$.foo["bar"]`, `$.bar[0]`, `$.bar[42]` `.name` | shorthand for `['name']` | `$.foo`, `$.foo.bar`, `$.bar[42].baz` Implementations MAY in addition support other JSONPath constructs, for example: @@ -211,18 +211,18 @@ Syntax Element | Description | Examples ---------------|-------------|-------- `[<selector>]` | index selector with negative integer array index (counts from the end of the array) | `$.bar[-1]` `[<selectors>]` | non-empty, comma-separated sequence of selectors | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]` -`..[<selectors>]` | [descendant segment](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#descendant-segment): selects zero or more descendants of a node; contains one or more selectors, separated by commas | `$.foo..["bar"]` +`..[<selectors>]` | [descendant segment](https://datatracker.ietf.org/doc/html/rfc9535#descendant-segment): selects zero or more descendants of a node; contains one or more selectors, separated by commas | `$.foo..["bar"]` `..name` | shorthand for `..['name']` | `$.foo..bar` -`*` | [wildcard selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#name-selector): selects all children of a node | `$.foo[*]`, `$[*]` -`.*` | shorthand for `[*]` | `$.foo.*`, `$.*` +`*` | [wildcard selector](https://datatracker.ietf.org/doc/html/rfc9535#name-selector): selects all children of a node | `$.foo[*]`, `$[*]` +`.*` | shorthand for `.[*]` | `$.foo.*`, `$.*` `..*` | shorthand for `..[*]` | `$.foo..*`, `$..*` `[start:end]` | array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:5]`, same as `$.bar[2,3,4]` `[start:]` | array subset from _start_ to end of array | `$.bar[2:]` `[:n]` | the first _n_ array items | `$.bar[:4]` `[-n:]` | the last _n_ array items | `$.bar[-3:]` -`[start:end:step]` | [array slice selector](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#slice) | -`[?<logical-expr>]` | [filter selector](): selects particular children using a logical expression | -`@` | [current node identifier](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#filter-selector) (valid only within filter selectors) | `$.bar[?@.baz==42]` +`[start:end:step]` | [array slice selector](https://datatracker.ietf.org/doc/html/rfc9535#slice) | +`[?<logical-expr>]` | [filter selector](https://datatracker.ietf.org/doc/html/rfc9535#filter-selector): selects particular children using a logical expression | +`@` | [current node identifier](https://datatracker.ietf.org/doc/html/rfc9535#filter-selector) (valid only within filter selectors) | `$.bar[?@.baz==42]` **References for JSONPath** - RFC 9535: https://datatracker.ietf.org/doc/html/rfc9535 From f2c28dd70c5fda6ee015dc8750065e8b5a096579 Mon Sep 17 00:00:00 2001 From: Ralf Handl Date: Thu, 29 Feb 2024 15:36:56 +0100 Subject: [PATCH 18/31] Align with RFC text --- vocabularies/Org.OData.JSON.V1.json | 2 +- vocabularies/Org.OData.JSON.V1.md | 4 ++-- vocabularies/Org.OData.JSON.V1.xml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/vocabularies/Org.OData.JSON.V1.json b/vocabularies/Org.OData.JSON.V1.json index 6f673ac3..48799190 100644 --- a/vocabularies/Org.OData.JSON.V1.json +++ b/vocabularies/Org.OData.JSON.V1.json @@ -111,7 +111,7 @@ "$Kind": "TypeDefinition", "$UnderlyingType": "Edm.String", "@Core.Description": "[JSONPath](https://datatracker.ietf.org/doc/html/rfc9535) expression", - "@Core.LongDescription": "Implementations SHOULD support at least the following subset of JSONPath:\n\nSyntax Element | Description | Examples\n---------------|-------------|--------\n`$` | [root identifier](https://datatracker.ietf.org/doc/html/rfc9535#root-identifier) | `$`\n`[]` | [child segment](https://datatracker.ietf.org/doc/html/rfc9535#child-segment) selects one child of a node; contains one [name selector](https://datatracker.ietf.org/doc/html/rfc9535#name-selector) (single- or double-quoted string using JSON escaping rules) or [index selector](https://datatracker.ietf.org/doc/html/rfc9535#index-selector) (non-negative decimal integer) | `$['foo']`, `$.foo[\"bar\"]`, `$.bar[0]`, `$.bar[42]`\n`.name` | shorthand for `['name']` | `$.foo`, `$.foo.bar`, `$.bar[42].baz`\n\nImplementations MAY in addition support other JSONPath constructs, for example:\n\nSyntax Element | Description | Examples\n---------------|-------------|--------\n`[]` | index selector with negative integer array index (counts from the end of the array) | `$.bar[-1]`\n`[]` | non-empty, comma-separated sequence of selectors | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]`\n`..[]` | [descendant segment](https://datatracker.ietf.org/doc/html/rfc9535#descendant-segment): selects zero or more descendants of a node; contains one or more selectors, separated by commas | `$.foo..[\"bar\"]`\n`..name` | shorthand for `..['name']` | `$.foo..bar`\n`*` | [wildcard selector](https://datatracker.ietf.org/doc/html/rfc9535#name-selector): selects all children of a node | `$.foo[*]`, `$[*]`\n`.*` | shorthand for `.[*]` | `$.foo.*`, `$.*`\n`..*` | shorthand for `..[*]` | `$.foo..*`, `$..*`\n`[start:end]` | array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:5]`, same as `$.bar[2,3,4]`\n`[start:]` | array subset from _start_ to end of array | `$.bar[2:]`\n`[:n]` | the first _n_ array items | `$.bar[:4]`\n`[-n:]` | the last _n_ array items | `$.bar[-3:]`\n`[start:end:step]` | [array slice selector](https://datatracker.ietf.org/doc/html/rfc9535#slice) |\n`[?]` | [filter selector](https://datatracker.ietf.org/doc/html/rfc9535#filter-selector): selects particular children using a logical expression | \n`@` | [current node identifier](https://datatracker.ietf.org/doc/html/rfc9535#filter-selector) (valid only within filter selectors) | `$.bar[?@.baz==42]`\n\n**References for JSONPath**\n- RFC 9535: https://datatracker.ietf.org/doc/html/rfc9535\n- Historic site: https://goessner.net/articles/JsonPath/\n- Node.js implementation: https://www.npmjs.com/package/jsonpath\n- Java implementation: https://github.com/json-path/JsonPath\n- Online evaluator: https://jsonpath.com/\n " + "@Core.LongDescription": "Implementations SHOULD support at least the following subset of JSONPath:\n\nSyntax Element | Description | Examples\n---------------|-------------|--------\n`$` | [root identifier](https://datatracker.ietf.org/doc/html/rfc9535#root-identifier) | `$`\n`[]` | [child segment](https://datatracker.ietf.org/doc/html/rfc9535#child-segment) selects one child of a node; contains one [name selector](https://datatracker.ietf.org/doc/html/rfc9535#name-selector) (single- or double-quoted string using JSON escaping rules) or [index selector](https://datatracker.ietf.org/doc/html/rfc9535#index-selector) (non-negative decimal integer) | `$['foo']`, `$.foo[\"bar\"]`, `$.bar[0]`, `$.bar[42]`\n`.name` | shorthand for `['name']` | `$.foo`, `$.foo.bar`, `$.bar[42].baz`\n\nImplementations MAY in addition support other JSONPath constructs, for example:\n\nSyntax Element | Description | Examples\n---------------|-------------|--------\n`[]` | index selector with negative integer array index (counts from the end of the array) | `$.bar[-1]`\n`[]` | non-empty, comma-separated sequence of selectors | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]`\n`..[]` | [descendant segment](https://datatracker.ietf.org/doc/html/rfc9535#descendant-segment): selects zero or more descendants of a node | `$.foo..[\"bar\"]`\n`..name` | shorthand for `..['name']` | `$.foo..bar`\n`*` | [wildcard selector](https://datatracker.ietf.org/doc/html/rfc9535#name-selector): selects all children of a node | `$.foo[*]`, `$[*]`\n`.*` | shorthand for `[*]` | `$.foo.*`, `$.*`\n`..*` | shorthand for `..[*]` | `$.foo..*`, `$..*`\n`[start:end]` | array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:5]`, same as `$.bar[2,3,4]`\n`[start:]` | array subset from _start_ to end of array | `$.bar[2:]`\n`[:n]` | the first _n_ array items | `$.bar[:4]`\n`[-n:]` | the last _n_ array items | `$.bar[-3:]`\n`[start:end:step]` | [array slice selector](https://datatracker.ietf.org/doc/html/rfc9535#slice) |\n`[?]` | [filter selector](https://datatracker.ietf.org/doc/html/rfc9535#filter-selector): selects particular children using a logical expression | \n`@` | [current node identifier](https://datatracker.ietf.org/doc/html/rfc9535#filter-selector) (valid only within filter selectors) | `$.bar[?@.baz==42]`\n\n**References for JSONPath**\n- RFC 9535: https://datatracker.ietf.org/doc/html/rfc9535\n- Historic site: https://goessner.net/articles/JsonPath/\n- Node.js implementation: https://www.npmjs.com/package/jsonpath\n- Java implementation: https://github.com/json-path/JsonPath\n- Online evaluator: https://jsonpath.com/\n " } } } \ No newline at end of file diff --git a/vocabularies/Org.OData.JSON.V1.md b/vocabularies/Org.OData.JSON.V1.md index 15e9be54..b1c3ee84 100644 --- a/vocabularies/Org.OData.JSON.V1.md +++ b/vocabularies/Org.OData.JSON.V1.md @@ -144,10 +144,10 @@ Syntax Element | Description | Examples ---------------|-------------|-------- `[]` | index selector with negative integer array index (counts from the end of the array) | `$.bar[-1]` `[]` | non-empty, comma-separated sequence of selectors | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]` -`..[]` | [descendant segment](https://datatracker.ietf.org/doc/html/rfc9535#descendant-segment): selects zero or more descendants of a node; contains one or more selectors, separated by commas | `$.foo..["bar"]` +`..[]` | [descendant segment](https://datatracker.ietf.org/doc/html/rfc9535#descendant-segment): selects zero or more descendants of a node | `$.foo..["bar"]` `..name` | shorthand for `..['name']` | `$.foo..bar` `*` | [wildcard selector](https://datatracker.ietf.org/doc/html/rfc9535#name-selector): selects all children of a node | `$.foo[*]`, `$[*]` -`.*` | shorthand for `.[*]` | `$.foo.*`, `$.*` +`.*` | shorthand for `[*]` | `$.foo.*`, `$.*` `..*` | shorthand for `..[*]` | `$.foo..*`, `$..*` `[start:end]` | array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:5]`, same as `$.bar[2,3,4]` `[start:]` | array subset from _start_ to end of array | `$.bar[2:]` diff --git a/vocabularies/Org.OData.JSON.V1.xml b/vocabularies/Org.OData.JSON.V1.xml index 51227c85..fc20876e 100644 --- a/vocabularies/Org.OData.JSON.V1.xml +++ b/vocabularies/Org.OData.JSON.V1.xml @@ -211,10 +211,10 @@ Syntax Element | Description | Examples ---------------|-------------|-------- `[<selector>]` | index selector with negative integer array index (counts from the end of the array) | `$.bar[-1]` `[<selectors>]` | non-empty, comma-separated sequence of selectors | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]` -`..[<selectors>]` | [descendant segment](https://datatracker.ietf.org/doc/html/rfc9535#descendant-segment): selects zero or more descendants of a node; contains one or more selectors, separated by commas | `$.foo..["bar"]` +`..[<selectors>]` | [descendant segment](https://datatracker.ietf.org/doc/html/rfc9535#descendant-segment): selects zero or more descendants of a node | `$.foo..["bar"]` `..name` | shorthand for `..['name']` | `$.foo..bar` `*` | [wildcard selector](https://datatracker.ietf.org/doc/html/rfc9535#name-selector): selects all children of a node | `$.foo[*]`, `$[*]` -`.*` | shorthand for `.[*]` | `$.foo.*`, `$.*` +`.*` | shorthand for `[*]` | `$.foo.*`, `$.*` `..*` | shorthand for `..[*]` | `$.foo..*`, `$..*` `[start:end]` | array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:5]`, same as `$.bar[2,3,4]` `[start:]` | array subset from _start_ to end of array | `$.bar[2:]` From d3a733637c1b35083975208ba8f7ba119c6c6746 Mon Sep 17 00:00:00 2001 From: Ralf Handl Date: Thu, 7 Mar 2024 08:57:50 +0100 Subject: [PATCH 19/31] MUST for minimum functionality --- vocabularies/Org.OData.JSON.V1.json | 2 +- vocabularies/Org.OData.JSON.V1.md | 2 +- vocabularies/Org.OData.JSON.V1.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/vocabularies/Org.OData.JSON.V1.json b/vocabularies/Org.OData.JSON.V1.json index 48799190..3f929129 100644 --- a/vocabularies/Org.OData.JSON.V1.json +++ b/vocabularies/Org.OData.JSON.V1.json @@ -111,7 +111,7 @@ "$Kind": "TypeDefinition", "$UnderlyingType": "Edm.String", "@Core.Description": "[JSONPath](https://datatracker.ietf.org/doc/html/rfc9535) expression", - "@Core.LongDescription": "Implementations SHOULD support at least the following subset of JSONPath:\n\nSyntax Element | Description | Examples\n---------------|-------------|--------\n`$` | [root identifier](https://datatracker.ietf.org/doc/html/rfc9535#root-identifier) | `$`\n`[]` | [child segment](https://datatracker.ietf.org/doc/html/rfc9535#child-segment) selects one child of a node; contains one [name selector](https://datatracker.ietf.org/doc/html/rfc9535#name-selector) (single- or double-quoted string using JSON escaping rules) or [index selector](https://datatracker.ietf.org/doc/html/rfc9535#index-selector) (non-negative decimal integer) | `$['foo']`, `$.foo[\"bar\"]`, `$.bar[0]`, `$.bar[42]`\n`.name` | shorthand for `['name']` | `$.foo`, `$.foo.bar`, `$.bar[42].baz`\n\nImplementations MAY in addition support other JSONPath constructs, for example:\n\nSyntax Element | Description | Examples\n---------------|-------------|--------\n`[]` | index selector with negative integer array index (counts from the end of the array) | `$.bar[-1]`\n`[]` | non-empty, comma-separated sequence of selectors | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]`\n`..[]` | [descendant segment](https://datatracker.ietf.org/doc/html/rfc9535#descendant-segment): selects zero or more descendants of a node | `$.foo..[\"bar\"]`\n`..name` | shorthand for `..['name']` | `$.foo..bar`\n`*` | [wildcard selector](https://datatracker.ietf.org/doc/html/rfc9535#name-selector): selects all children of a node | `$.foo[*]`, `$[*]`\n`.*` | shorthand for `[*]` | `$.foo.*`, `$.*`\n`..*` | shorthand for `..[*]` | `$.foo..*`, `$..*`\n`[start:end]` | array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:5]`, same as `$.bar[2,3,4]`\n`[start:]` | array subset from _start_ to end of array | `$.bar[2:]`\n`[:n]` | the first _n_ array items | `$.bar[:4]`\n`[-n:]` | the last _n_ array items | `$.bar[-3:]`\n`[start:end:step]` | [array slice selector](https://datatracker.ietf.org/doc/html/rfc9535#slice) |\n`[?]` | [filter selector](https://datatracker.ietf.org/doc/html/rfc9535#filter-selector): selects particular children using a logical expression | \n`@` | [current node identifier](https://datatracker.ietf.org/doc/html/rfc9535#filter-selector) (valid only within filter selectors) | `$.bar[?@.baz==42]`\n\n**References for JSONPath**\n- RFC 9535: https://datatracker.ietf.org/doc/html/rfc9535\n- Historic site: https://goessner.net/articles/JsonPath/\n- Node.js implementation: https://www.npmjs.com/package/jsonpath\n- Java implementation: https://github.com/json-path/JsonPath\n- Online evaluator: https://jsonpath.com/\n " + "@Core.LongDescription": "Implementations MUST support at least the following subset of JSONPath:\n\nSyntax Element | Description | Examples\n---------------|-------------|--------\n`$` | [root identifier](https://datatracker.ietf.org/doc/html/rfc9535#root-identifier) | `$`\n`[]` | [child segment](https://datatracker.ietf.org/doc/html/rfc9535#child-segment) selects one child of a node; contains one [name selector](https://datatracker.ietf.org/doc/html/rfc9535#name-selector) (single- or double-quoted string using JSON escaping rules) or [index selector](https://datatracker.ietf.org/doc/html/rfc9535#index-selector) (non-negative decimal integer) | `$['foo']`, `$.foo[\"bar\"]`, `$.bar[0]`, `$.bar[42]`\n`.name` | shorthand for `['name']` | `$.foo`, `$.foo.bar`, `$.bar[42].baz`\n\nImplementations MAY in addition support other JSONPath constructs, for example:\n\nSyntax Element | Description | Examples\n---------------|-------------|--------\n`[]` | index selector with negative integer array index (counts from the end of the array) | `$.bar[-1]`\n`[]` | non-empty, comma-separated sequence of selectors | `$.foo['bar','baz']`, `$.bar[0,1,2,3,5,7,11]`\n`..[]` | [descendant segment](https://datatracker.ietf.org/doc/html/rfc9535#descendant-segment): selects zero or more descendants of a node | `$.foo..[\"bar\"]`\n`..name` | shorthand for `..['name']` | `$.foo..bar`\n`*` | [wildcard selector](https://datatracker.ietf.org/doc/html/rfc9535#name-selector): selects all children of a node | `$.foo[*]`, `$[*]`\n`.*` | shorthand for `[*]` | `$.foo.*`, `$.*`\n`..*` | shorthand for `..[*]` | `$.foo..*`, `$..*`\n`[start:end]` | array subset by range of indices (including the item at _start_ and excluding the item at _end_ | `$.bar[2:5]`, same as `$.bar[2,3,4]`\n`[start:]` | array subset from _start_ to end of array | `$.bar[2:]`\n`[:n]` | the first _n_ array items | `$.bar[:4]`\n`[-n:]` | the last _n_ array items | `$.bar[-3:]`\n`[start:end:step]` | [array slice selector](https://datatracker.ietf.org/doc/html/rfc9535#slice) |\n`[?]` | [filter selector](https://datatracker.ietf.org/doc/html/rfc9535#filter-selector): selects particular children using a logical expression | \n`@` | [current node identifier](https://datatracker.ietf.org/doc/html/rfc9535#filter-selector) (valid only within filter selectors) | `$.bar[?@.baz==42]`\n\n**References for JSONPath**\n- RFC 9535: https://datatracker.ietf.org/doc/html/rfc9535\n- Historic site: https://goessner.net/articles/JsonPath/\n- Node.js implementation: https://www.npmjs.com/package/jsonpath\n- Java implementation: https://github.com/json-path/JsonPath\n- Online evaluator: https://jsonpath.com/\n " } } } \ No newline at end of file diff --git a/vocabularies/Org.OData.JSON.V1.md b/vocabularies/Org.OData.JSON.V1.md index b1c3ee84..dbd40eee 100644 --- a/vocabularies/Org.OData.JSON.V1.md +++ b/vocabularies/Org.OData.JSON.V1.md @@ -130,7 +130,7 @@ Textual data of media type `application/json` [JSONPath](https://datatracker.ietf.org/doc/html/rfc9535) expression -Implementations SHOULD support at least the following subset of JSONPath: +Implementations MUST support at least the following subset of JSONPath: Syntax Element | Description | Examples ---------------|-------------|-------- diff --git a/vocabularies/Org.OData.JSON.V1.xml b/vocabularies/Org.OData.JSON.V1.xml index fc20876e..4319986c 100644 --- a/vocabularies/Org.OData.JSON.V1.xml +++ b/vocabularies/Org.OData.JSON.V1.xml @@ -197,7 +197,7 @@ If a single non-null scalar JSON value is identified by `path` within `input`, t - Implementations SHOULD support at least the following subset of JSONPath: + Implementations MUST support at least the following subset of JSONPath: Syntax Element | Description | Examples ---------------|-------------|-------- From e2ac582a0b8b5fe6432fc80e1a66919c8d2d1352 Mon Sep 17 00:00:00 2001 From: Ralf Handl Date: Thu, 7 Mar 2024 12:28:10 +0100 Subject: [PATCH 20/31] JSON data instead of JSON stream --- vocabularies/Org.OData.JSON.V1.json | 4 ++-- vocabularies/Org.OData.JSON.V1.md | 12 ++++++------ vocabularies/Org.OData.JSON.V1.xml | 14 +++++++------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/vocabularies/Org.OData.JSON.V1.json b/vocabularies/Org.OData.JSON.V1.json index 3f929129..023b296a 100644 --- a/vocabularies/Org.OData.JSON.V1.json +++ b/vocabularies/Org.OData.JSON.V1.json @@ -12,8 +12,8 @@ }, "Org.OData.JSON.V1": { "$Alias": "JSON", - "@Core.Description": "Terms, types, and functions for JSON streams", - "@Core.LongDescription": "OData [stream properties](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ManagingStreamProperties) allow embedding data of arbitrary media types,\nand the OData JSON format allows [direct embedding of JSON data](https://docs.oasis-open.org/odata/odata-json-format/v4.01/odata-json-format-v4.01.html#sec_StreamProperty) in request and response payloads.\n \nThis vocabulary defines a convenience [type for JSON streams](#JSON) streams as well as a term for referencing a [JSON Schema](#Schema) describing the structure of the JSON stream. \n\nIn addition it defines two functions for [querying](#query) JSON streams and using a [primitive value](#value) extracted from a JSON stream in common expressions, for example in `$filter`, `$orderby`, or `$compute`.\n\n**Example**\n\nThe `Employees` entity set has a JSON stream property `resume`:\n```json\n\"container\": {\n \"$Kind\": \"EntityContainer\",\n \"Employees\": { \"$Collection\": true, \"$Type\": \"this.Employee\" }\n},\n\"Employee\": {\n \"$Kind\": \"EntityType\",\n \"$Key\": [\"empid\"],\n \"empid\": { \"$Type\": \"Edm.Int32\" },\n \"resume\": { \"$Type\": \"JSON.JSON\", \"$Nullable\": true }\n}\n```\n\nOne of its entities has a `resume` value of\n```json\n{ \n \"ssn\": \"1234\", \n \"lastname\": \"Doe\", \n \"address\": {\n \"zipcode\": \"10022\", \n \"street\": \"ABC st\"\n },\n \"experience\": \"excellent\"\n}\n```\n\nThis allows to filter and sort by values in that resume, and extract parts of the resume as a dynamic JSON stream property\n```http\nGET http://www.example.com/mycompany/Employees\n ?$filter=resume/JSON.value('$.lastname') eq 'Doe'\n &$orderby=resume/JSON.value('$.experience')\n &$compute=resume/JSON.query('$.address') as address\n &$expand=address\n```\nreceiving\n```json\n{ \n \"@odata.context\": \"$metadata#Employees\", \n \"value\": [ \n {\n \"empid\": 4711,\n \"address\": {\n \"zipcode\": \"10022\", \n \"street\": \"ABC st\"\n }\n },\n ...\n ]\n}\n```\n ", + "@Core.Description": "Terms, types, and functions for JSON data", + "@Core.LongDescription": "OData [stream properties](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ManagingStreamProperties) allow embedding data of arbitrary media types,\nand the OData JSON format allows [direct embedding of JSON data](https://docs.oasis-open.org/odata/odata-json-format/v4.01/odata-json-format-v4.01.html#sec_StreamProperty) in request and response payloads.\n\nThis vocabulary defines a convenience [type for JSON data](#JSON) as well as a term for referencing a [JSON Schema](#Schema) describing the structure of the JSON data.\n\nIn addition it defines two functions for [querying](#query) JSON data and using a [primitive value](#value) extracted from JSON data in common expressions, for example in `$filter`, `$orderby`, or `$compute`.\n\n**Example**\n\nThe `Employees` entity set has a JSON data property `resume`:\n```json\n\"container\": {\n \"$Kind\": \"EntityContainer\",\n \"Employees\": { \"$Collection\": true, \"$Type\": \"this.Employee\" }\n},\n\"Employee\": {\n \"$Kind\": \"EntityType\",\n \"$Key\": [\"empid\"],\n \"empid\": { \"$Type\": \"Edm.Int32\" },\n \"resume\": { \"$Type\": \"JSON.JSON\", \"$Nullable\": true }\n}\n```\n\nOne of its entities has a `resume` value of\n```json\n{ \n \"ssn\": \"1234\", \n \"lastname\": \"Doe\", \n \"address\": {\n \"zipcode\": \"10022\", \n \"street\": \"ABC st\"\n },\n \"experience\": \"excellent\"\n}\n```\n\nThis allows to filter and sort by values in that resume, and extract parts of the resume as a dynamic JSON data property\n```http\nGET http://www.example.com/mycompany/Employees\n ?$filter=resume/JSON.value('$.lastname') eq 'Doe'\n &$orderby=resume/JSON.value('$.experience')\n &$compute=resume/JSON.query('$.address') as address\n &$expand=address\n```\nreceiving\n```json\n{ \n \"@odata.context\": \"$metadata#Employees\", \n \"value\": [ \n {\n \"empid\": 4711,\n \"address\": {\n \"zipcode\": \"10022\", \n \"street\": \"ABC st\"\n }\n },\n ...\n ]\n}\n```\n ", "@Core.Links": [ { "rel": "alternate", diff --git a/vocabularies/Org.OData.JSON.V1.md b/vocabularies/Org.OData.JSON.V1.md index dbd40eee..0562d9d8 100644 --- a/vocabularies/Org.OData.JSON.V1.md +++ b/vocabularies/Org.OData.JSON.V1.md @@ -1,18 +1,18 @@ # JSON Vocabulary **Namespace: [Org.OData.JSON.V1](Org.OData.JSON.V1.xml)** -Terms, types, and functions for JSON streams +Terms, types, and functions for JSON data OData [stream properties](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ManagingStreamProperties) allow embedding data of arbitrary media types, and the OData JSON format allows [direct embedding of JSON data](https://docs.oasis-open.org/odata/odata-json-format/v4.01/odata-json-format-v4.01.html#sec_StreamProperty) in request and response payloads. - -This vocabulary defines a convenience [type for JSON streams](#JSON) streams as well as a term for referencing a [JSON Schema](#Schema) describing the structure of the JSON stream. -In addition it defines two functions for [querying](#query) JSON streams and using a [primitive value](#value) extracted from a JSON stream in common expressions, for example in `$filter`, `$orderby`, or `$compute`. +This vocabulary defines a convenience [type for JSON data](#JSON) as well as a term for referencing a [JSON Schema](#Schema) describing the structure of the JSON data. + +In addition it defines two functions for [querying](#query) JSON data and using a [primitive value](#value) extracted from JSON data in common expressions, for example in `$filter`, `$orderby`, or `$compute`. **Example** -The `Employees` entity set has a JSON stream property `resume`: +The `Employees` entity set has a JSON data property `resume`: ```json "container": { "$Kind": "EntityContainer", @@ -39,7 +39,7 @@ One of its entities has a `resume` value of } ``` -This allows to filter and sort by values in that resume, and extract parts of the resume as a dynamic JSON stream property +This allows to filter and sort by values in that resume, and extract parts of the resume as a dynamic JSON data property ```http GET http://www.example.com/mycompany/Employees ?$filter=resume/JSON.value('$.lastname') eq 'Doe' diff --git a/vocabularies/Org.OData.JSON.V1.xml b/vocabularies/Org.OData.JSON.V1.xml index 4319986c..20e3c4d8 100644 --- a/vocabularies/Org.OData.JSON.V1.xml +++ b/vocabularies/Org.OData.JSON.V1.xml @@ -35,7 +35,7 @@ - OData Extension for Data Aggregation Version 4.0. Latest version: http://docs.oasis-open.org/odata/odata-data-aggregation-ext/v4.0/odata-data-aggregation-ext-v4.0.html. Abstract: - This document defines terms, types, and functions for JSON streams. + This document defines terms, types, and functions for JSON data. --> @@ -45,19 +45,19 @@ - Terms, types, and functions for JSON streams + Terms, types, and functions for JSON data OData [stream properties](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ManagingStreamProperties) allow embedding data of arbitrary media types, and the OData JSON format allows [direct embedding of JSON data](https://docs.oasis-open.org/odata/odata-json-format/v4.01/odata-json-format-v4.01.html#sec_StreamProperty) in request and response payloads. - -This vocabulary defines a convenience [type for JSON streams](#JSON) streams as well as a term for referencing a [JSON Schema](#Schema) describing the structure of the JSON stream. -In addition it defines two functions for [querying](#query) JSON streams and using a [primitive value](#value) extracted from a JSON stream in common expressions, for example in `$filter`, `$orderby`, or `$compute`. +This vocabulary defines a convenience [type for JSON data](#JSON) as well as a term for referencing a [JSON Schema](#Schema) describing the structure of the JSON data. + +In addition it defines two functions for [querying](#query) JSON data and using a [primitive value](#value) extracted from JSON data in common expressions, for example in `$filter`, `$orderby`, or `$compute`. **Example** -The `Employees` entity set has a JSON stream property `resume`: +The `Employees` entity set has a JSON data property `resume`: ```json "container": { "$Kind": "EntityContainer", @@ -84,7 +84,7 @@ One of its entities has a `resume` value of } ``` -This allows to filter and sort by values in that resume, and extract parts of the resume as a dynamic JSON stream property +This allows to filter and sort by values in that resume, and extract parts of the resume as a dynamic JSON data property ```http GET http://www.example.com/mycompany/Employees ?$filter=resume/JSON.value('$.lastname') eq 'Doe' From 24d78aba4e3298d2843f268f7e61bdd8d2ddfb22 Mon Sep 17 00:00:00 2001 From: Ralf Handl Date: Thu, 14 Mar 2024 11:04:52 +0100 Subject: [PATCH 21/31] name=value syntax for function calls --- vocabularies/Org.OData.JSON.V1.json | 2 +- vocabularies/Org.OData.JSON.V1.md | 28 ++++----- vocabularies/Org.OData.JSON.V1.xml | 90 +++++++++++++++++++---------- 3 files changed, 74 insertions(+), 46 deletions(-) diff --git a/vocabularies/Org.OData.JSON.V1.json b/vocabularies/Org.OData.JSON.V1.json index 023b296a..342057c6 100644 --- a/vocabularies/Org.OData.JSON.V1.json +++ b/vocabularies/Org.OData.JSON.V1.json @@ -13,7 +13,7 @@ "Org.OData.JSON.V1": { "$Alias": "JSON", "@Core.Description": "Terms, types, and functions for JSON data", - "@Core.LongDescription": "OData [stream properties](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ManagingStreamProperties) allow embedding data of arbitrary media types,\nand the OData JSON format allows [direct embedding of JSON data](https://docs.oasis-open.org/odata/odata-json-format/v4.01/odata-json-format-v4.01.html#sec_StreamProperty) in request and response payloads.\n\nThis vocabulary defines a convenience [type for JSON data](#JSON) as well as a term for referencing a [JSON Schema](#Schema) describing the structure of the JSON data.\n\nIn addition it defines two functions for [querying](#query) JSON data and using a [primitive value](#value) extracted from JSON data in common expressions, for example in `$filter`, `$orderby`, or `$compute`.\n\n**Example**\n\nThe `Employees` entity set has a JSON data property `resume`:\n```json\n\"container\": {\n \"$Kind\": \"EntityContainer\",\n \"Employees\": { \"$Collection\": true, \"$Type\": \"this.Employee\" }\n},\n\"Employee\": {\n \"$Kind\": \"EntityType\",\n \"$Key\": [\"empid\"],\n \"empid\": { \"$Type\": \"Edm.Int32\" },\n \"resume\": { \"$Type\": \"JSON.JSON\", \"$Nullable\": true }\n}\n```\n\nOne of its entities has a `resume` value of\n```json\n{ \n \"ssn\": \"1234\", \n \"lastname\": \"Doe\", \n \"address\": {\n \"zipcode\": \"10022\", \n \"street\": \"ABC st\"\n },\n \"experience\": \"excellent\"\n}\n```\n\nThis allows to filter and sort by values in that resume, and extract parts of the resume as a dynamic JSON data property\n```http\nGET http://www.example.com/mycompany/Employees\n ?$filter=resume/JSON.value('$.lastname') eq 'Doe'\n &$orderby=resume/JSON.value('$.experience')\n &$compute=resume/JSON.query('$.address') as address\n &$expand=address\n```\nreceiving\n```json\n{ \n \"@odata.context\": \"$metadata#Employees\", \n \"value\": [ \n {\n \"empid\": 4711,\n \"address\": {\n \"zipcode\": \"10022\", \n \"street\": \"ABC st\"\n }\n },\n ...\n ]\n}\n```\n ", + "@Core.LongDescription": "OData [stream properties](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ManagingStreamProperties) allow embedding data of arbitrary media types,\nand the OData JSON format allows [direct embedding of JSON data](https://docs.oasis-open.org/odata/odata-json-format/v4.01/odata-json-format-v4.01.html#sec_StreamProperty) in request and response payloads.\n\nThis vocabulary defines a convenience [type for JSON data](#JSON) as well as a term for referencing a [JSON Schema](#Schema) describing the structure of the JSON data.\n\nIn addition it defines two functions for [querying](#query) JSON data and using a [primitive value](#value) extracted from JSON data in common expressions, for example in `$filter`, `$orderby`, or `$compute`.\n\n**Example**\n\nThe `Employees` entity set has a JSON data property `resume`:\n```json\n\"container\": {\n \"$Kind\": \"EntityContainer\",\n \"Employees\": { \"$Collection\": true, \"$Type\": \"this.Employee\" }\n},\n\"Employee\": {\n \"$Kind\": \"EntityType\",\n \"$Key\": [\"empid\"],\n \"empid\": { \"$Type\": \"Edm.Int32\" },\n \"resume\": { \"$Type\": \"JSON.JSON\", \"$Nullable\": true }\n}\n```\n\nOne of its entities has a `resume` value of\n```json\n{ \n \"ssn\": \"1234\", \n \"lastname\": \"Doe\", \n \"address\": {\n \"zipcode\": \"10022\", \n \"street\": \"ABC st\"\n },\n \"experience\": \"excellent\"\n}\n```\n\nThis allows to filter and sort by values in that resume, and extract parts of the resume as a dynamic JSON data property\n```http\nGET http://www.example.com/mycompany/Employees\n ?$filter=resume/JSON.value(path='$.lastname') eq 'Doe'\n &$orderby=resume/JSON.value(path='$.experience')\n &$compute=resume/JSON.query(path='$.address') as address\n &$expand=address\n```\nreceiving\n```json\n{ \n \"@odata.context\": \"$metadata#Employees\", \n \"value\": [ \n {\n \"empid\": 4711,\n \"address\": {\n \"zipcode\": \"10022\", \n \"street\": \"ABC st\"\n }\n },\n ...\n ]\n}\n```\n ", "@Core.Links": [ { "rel": "alternate", diff --git a/vocabularies/Org.OData.JSON.V1.md b/vocabularies/Org.OData.JSON.V1.md index 0562d9d8..6bb84173 100644 --- a/vocabularies/Org.OData.JSON.V1.md +++ b/vocabularies/Org.OData.JSON.V1.md @@ -42,9 +42,9 @@ One of its entities has a `resume` value of This allows to filter and sort by values in that resume, and extract parts of the resume as a dynamic JSON data property ```http GET http://www.example.com/mycompany/Employees - ?$filter=resume/JSON.value('$.lastname') eq 'Doe' - &$orderby=resume/JSON.value('$.experience') - &$compute=resume/JSON.query('$.address') as address + ?$filter=resume/JSON.value(path='$.lastname') eq 'Doe' + &$orderby=resume/JSON.value(path='$.experience') + &$compute=resume/JSON.query(path='$.address') as address &$expand=address ``` receiving @@ -70,13 +70,13 @@ receiving Term|Type|Description :---|:---|:---------- -[Schema](./Org.OData.JSON.V1.xml#L131:~:text=The JSON Schema for JSON values of the annotated media entity type, property, parameter, return type, term, or type definition
The schema can be a reference, i.e. `{"$ref":"url/of/schemafile#/path/to/schema/within/schemafile"}` +[Schema](./Org.OData.JSON.V1.xml#L151:~:text=The JSON Schema for JSON values of the annotated media entity type, property, parameter, return type, term, or type definition
The schema can be a reference, i.e. `{"$ref":"url/of/schemafile#/path/to/schema/within/schemafile"}` ## Functions -### [query](./Org.OData.JSON.V1.xml#L139:~:text= -### [value](./Org.OData.JSON.V1.xml#L160:~:text= -## [JSON](./Org.OData.JSON.V1.xml#L186:~:text= -## [Path](./Org.OData.JSON.V1.xml#L197:~:text= - + - + Terms, types, and functions for JSON data @@ -87,9 +103,9 @@ One of its entities has a `resume` value of This allows to filter and sort by values in that resume, and extract parts of the resume as a dynamic JSON data property ```http GET http://www.example.com/mycompany/Employees - ?$filter=resume/JSON.value('$.lastname') eq 'Doe' - &$orderby=resume/JSON.value('$.experience') - &$compute=resume/JSON.query('$.address') as address + ?$filter=resume/JSON.value(path='$.lastname') eq 'Doe' + &$orderby=resume/JSON.value(path='$.experience') + &$compute=resume/JSON.query(path='$.address') as address &$expand=address ``` receiving @@ -115,29 +131,35 @@ receiving - + - + - +
- + - + The schema can be a reference, i.e. `{"$ref":"url/of/schemafile#/path/to/schema/within/schemafile"}` - + Extracts a JSON value, such as an array, object, or a JSON scalar value (string, number, boolean, or `null`) from the `input` JSON value: - If `path` only consists of the root identifier followed by name and index selectors, it returns the identified single node within `input`, or `null` if no node is identified. @@ -150,15 +172,18 @@ receiving
- + - + - + Extracts a single OData primitive value from the `input` JSON value: - If `path` only consists of the root identifier followed by name and index selectors and identifies a single scalar JSON value (string, number, boolean, or `null`) within `input`, it returns the identified single value cast to an OData primitive value (see below). @@ -176,10 +201,12 @@ If a single non-null scalar JSON value is identified by `path` within `input`, t - + - + @@ -195,7 +222,8 @@ If a single non-null scalar JSON value is identified by `path` within `input`, t - + Implementations MUST support at least the following subset of JSONPath: From d41ef8de221c8c9a67c8582231272ce0f01ff241 Mon Sep 17 00:00:00 2001 From: Ralf Handl Date: Thu, 14 Mar 2024 15:18:56 +0100 Subject: [PATCH 22/31] Update vocabularies/Org.OData.JSON.V1.xml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Heiko Theißen --- vocabularies/Org.OData.JSON.V1.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vocabularies/Org.OData.JSON.V1.xml b/vocabularies/Org.OData.JSON.V1.xml index ce36f8e6..9098a551 100644 --- a/vocabularies/Org.OData.JSON.V1.xml +++ b/vocabularies/Org.OData.JSON.V1.xml @@ -191,6 +191,8 @@ receiving - If `input` is not a valid JSON value, the function returns `null`. - If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input` (for example applying an index selector to a scalar value), the function returns `null`. +If null is identified by `path` within `input`, the function returns null. + If a single non-null scalar JSON value is identified by `path` within `input`, the function returns that value as an OData primitive value of type - `Edm.String` if the value is a JSON string - `Edm.Boolean` if the value is `true` or `false` From ac67e0b82a14d5c66ddbb65d762b2a861037d2ce Mon Sep 17 00:00:00 2001 From: Ralf Handl Date: Thu, 14 Mar 2024 15:21:09 +0100 Subject: [PATCH 23/31] Update Org.OData.JSON.V1.xml --- vocabularies/Org.OData.JSON.V1.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/vocabularies/Org.OData.JSON.V1.xml b/vocabularies/Org.OData.JSON.V1.xml index 9098a551..ce36f8e6 100644 --- a/vocabularies/Org.OData.JSON.V1.xml +++ b/vocabularies/Org.OData.JSON.V1.xml @@ -191,8 +191,6 @@ receiving - If `input` is not a valid JSON value, the function returns `null`. - If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input` (for example applying an index selector to a scalar value), the function returns `null`. -If null is identified by `path` within `input`, the function returns null. - If a single non-null scalar JSON value is identified by `path` within `input`, the function returns that value as an OData primitive value of type - `Edm.String` if the value is a JSON string - `Edm.Boolean` if the value is `true` or `false` From e0c93ac4cd52476b462a41b5833e1dd521285d25 Mon Sep 17 00:00:00 2001 From: Ralf Handl Date: Thu, 14 Mar 2024 15:38:36 +0100 Subject: [PATCH 24/31] Heiko's comment --- vocabularies/Org.OData.JSON.V1.json | 2 +- vocabularies/Org.OData.JSON.V1.md | 21 +++++++++++---------- vocabularies/Org.OData.JSON.V1.xml | 11 ++++++----- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/vocabularies/Org.OData.JSON.V1.json b/vocabularies/Org.OData.JSON.V1.json index 342057c6..2cb891a5 100644 --- a/vocabularies/Org.OData.JSON.V1.json +++ b/vocabularies/Org.OData.JSON.V1.json @@ -76,7 +76,7 @@ "$Kind": "Function", "$IsBound": true, "@Core.Description": "Query a stream value of media type `application/json`, returning an OData primitive value", - "@Core.LongDescription": "Extracts a single OData primitive value from the `input` JSON value:\n- If `path` only consists of the root identifier followed by name and index selectors and identifies a single scalar JSON value (string, number, boolean, or `null`) within `input`, it returns the identified single value cast to an OData primitive value (see below).\n- If `path` identifies multiple nodes within `input` (by using descendant, wildcard, union, array subset, or filter selectors), identifies an object or array, or does not identify any node, the function returns `null`.\n- If `input` is not a valid JSON value, the function returns `null`.\n- If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input` (for example applying an index selector to a scalar value), the function returns `null`.\n\nIf a single non-null scalar JSON value is identified by `path` within `input`, the function returns that value as an OData primitive value of type\n- `Edm.String` if the value is a JSON string\n- `Edm.Boolean` if the value is `true` or `false`\n- `Edm.Decimal` with unspecified precision and floating scale if the value is a JSON number\n ", + "@Core.LongDescription": "Extracts a single OData primitive value from the `input` JSON value:\n- If `path` only consists of the root identifier followed by name and index selectors and identifies a single scalar JSON value (string, number, boolean, or `null`) within `input`, it returns the identified single value, cast to an OData primitive value (see below).\n- If `path` identifies multiple nodes within `input` (by using descendant, wildcard, union, array subset, or filter selectors), identifies an object or array, or does not identify any node, the function returns `null`.\n- If `input` is not a valid JSON value, the function returns `null`.\n- If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input` (for example applying an index selector to a scalar value), the function returns `null`.\n\nIf a single scalar JSON value is identified by `path` within `input`, the function returns that value as an OData primitive value:\n- `null` is returned as `null`\n- `true` or `false` are returned as the corresponding `Edm.Boolean` values \n- numbers are returned as `Edm.Decimal` values with unspecified precision and floating scale\n- strings are returned as `Edm.String` values\n ", "$Parameter": [ { "$Name": "input", diff --git a/vocabularies/Org.OData.JSON.V1.md b/vocabularies/Org.OData.JSON.V1.md index 6bb84173..407657bb 100644 --- a/vocabularies/Org.OData.JSON.V1.md +++ b/vocabularies/Org.OData.JSON.V1.md @@ -100,32 +100,33 @@ Parameter|Type|Description Query a stream value of media type `application/json`, returning an OData primitive value Extracts a single OData primitive value from the `input` JSON value: -- If `path` only consists of the root identifier followed by name and index selectors and identifies a single scalar JSON value (string, number, boolean, or `null`) within `input`, it returns the identified single value cast to an OData primitive value (see below). +- If `path` only consists of the root identifier followed by name and index selectors and identifies a single scalar JSON value (string, number, boolean, or `null`) within `input`, it returns the identified single value, cast to an OData primitive value (see below). - If `path` identifies multiple nodes within `input` (by using descendant, wildcard, union, array subset, or filter selectors), identifies an object or array, or does not identify any node, the function returns `null`. - If `input` is not a valid JSON value, the function returns `null`. - If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input` (for example applying an index selector to a scalar value), the function returns `null`. -If a single non-null scalar JSON value is identified by `path` within `input`, the function returns that value as an OData primitive value of type -- `Edm.String` if the value is a JSON string -- `Edm.Boolean` if the value is `true` or `false` -- `Edm.Decimal` with unspecified precision and floating scale if the value is a JSON number +If a single scalar JSON value is identified by `path` within `input`, the function returns that value as an OData primitive value: +- `null` is returned as `null` +- `true` or `false` are returned as the corresponding `Edm.Boolean` values +- numbers are returned as `Edm.Decimal` values with unspecified precision and floating scale +- strings are returned as `Edm.String` values Parameter|Type|Description :--------|:---|:---------- -**[input](./Org.OData.JSON.V1.xml#L200:~:text= -## [JSON](./Org.OData.JSON.V1.xml#L213:~:text= -## [Path](./Org.OData.JSON.V1.xml#L224:~:text= Extracts a single OData primitive value from the `input` JSON value: -- If `path` only consists of the root identifier followed by name and index selectors and identifies a single scalar JSON value (string, number, boolean, or `null`) within `input`, it returns the identified single value cast to an OData primitive value (see below). +- If `path` only consists of the root identifier followed by name and index selectors and identifies a single scalar JSON value (string, number, boolean, or `null`) within `input`, it returns the identified single value, cast to an OData primitive value (see below). - If `path` identifies multiple nodes within `input` (by using descendant, wildcard, union, array subset, or filter selectors), identifies an object or array, or does not identify any node, the function returns `null`. - If `input` is not a valid JSON value, the function returns `null`. - If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input` (for example applying an index selector to a scalar value), the function returns `null`. -If a single non-null scalar JSON value is identified by `path` within `input`, the function returns that value as an OData primitive value of type -- `Edm.String` if the value is a JSON string -- `Edm.Boolean` if the value is `true` or `false` -- `Edm.Decimal` with unspecified precision and floating scale if the value is a JSON number +If a single scalar JSON value is identified by `path` within `input`, the function returns that value as an OData primitive value: +- `null` is returned as `null` +- `true` or `false` are returned as the corresponding `Edm.Boolean` values +- numbers are returned as `Edm.Decimal` values with unspecified precision and floating scale +- strings are returned as `Edm.String` values From 1b5c5715b7b4559418af92ab3252a390be6f0a8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20Thei=C3=9Fen?= Date: Thu, 4 Apr 2024 12:10:44 +0200 Subject: [PATCH 25/31] Return-type-specific value functions --- vocabularies/Org.OData.JSON.V1.json | 61 +++++++++++++++++++++++++++-- vocabularies/Org.OData.JSON.V1.md | 49 +++++++++++++++++------ vocabularies/Org.OData.JSON.V1.xml | 47 ++++++++++++++++------ 3 files changed, 130 insertions(+), 27 deletions(-) diff --git a/vocabularies/Org.OData.JSON.V1.json b/vocabularies/Org.OData.JSON.V1.json index 2cb891a5..8629b950 100644 --- a/vocabularies/Org.OData.JSON.V1.json +++ b/vocabularies/Org.OData.JSON.V1.json @@ -75,8 +75,8 @@ { "$Kind": "Function", "$IsBound": true, - "@Core.Description": "Query a stream value of media type `application/json`, returning an OData primitive value", - "@Core.LongDescription": "Extracts a single OData primitive value from the `input` JSON value:\n- If `path` only consists of the root identifier followed by name and index selectors and identifies a single scalar JSON value (string, number, boolean, or `null`) within `input`, it returns the identified single value, cast to an OData primitive value (see below).\n- If `path` identifies multiple nodes within `input` (by using descendant, wildcard, union, array subset, or filter selectors), identifies an object or array, or does not identify any node, the function returns `null`.\n- If `input` is not a valid JSON value, the function returns `null`.\n- If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input` (for example applying an index selector to a scalar value), the function returns `null`.\n\nIf a single scalar JSON value is identified by `path` within `input`, the function returns that value as an OData primitive value:\n- `null` is returned as `null`\n- `true` or `false` are returned as the corresponding `Edm.Boolean` values \n- numbers are returned as `Edm.Decimal` values with unspecified precision and floating scale\n- strings are returned as `Edm.String` values\n ", + "@Core.Description": "Query a stream value of media type `application/json`, returning a string", + "@Core.LongDescription": "Extracts a single OData primitive value from the `input` JSON value and casts it to a string:\n- If `path` only consists of the root identifier followed by name and index selectors and identifies a single scalar JSON value (string, number, boolean, or `null`) within `input`, it returns the identified single value, cast to an OData primitive value (see below).\n- If `path` identifies multiple nodes within `input` (by using descendant, wildcard, union, array subset, or filter selectors), identifies an object or array, or does not identify any node, the function returns `null`.\n- If `input` is not a valid JSON value, the function returns `null`.\n- If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input` (for example applying an index selector to a scalar value), the function returns `null`.", "$Parameter": [ { "$Name": "input", @@ -94,7 +94,62 @@ "$ReturnType": { "$Type": "Edm.PrimitiveType", "$Nullable": true, - "@Core.Description": "OData primitive value resulting from applying `path` to `input`" + "@Core.Description": "String value resulting from applying `path` to `input`" + } + } + ], + "valueNumber": [ + { + "$Kind": "Function", + "$IsBound": true, + "@Core.Description": "Query a stream value of media type `application/json`, returning a number", + "@Core.LongDescription": "Like [`value`](#value), but casts the extracted value to an `Edm.Decimal` with unspecified precision and floating scale.\n Returns null if that cast fails.", + "$Parameter": [ + { + "$Name": "input", + "$Type": "JSON.JSON", + "$Nullable": true, + "@Core.Description": "JSON input" + }, + { + "$Name": "path", + "$Type": "JSON.Path", + "$Nullable": true, + "@Core.Description": "JSONPath expression to be applied to value of `expr`" + } + ], + "$ReturnType": { + "$Type": "Edm.Decimal", + "$Nullable": true, + "$Scale": "floating", + "@Core.Description": "Numeric value resulting from applying `path` to `input`" + } + } + ], + "valueBoolean": [ + { + "$Kind": "Function", + "$IsBound": true, + "@Core.Description": "Query a stream value of media type `application/json`, returning a Boolean", + "@Core.LongDescription": "Like [`value`](#value), but casts the extracted value to an `Edm.Boolean`.\n Returns null if that cast fails.", + "$Parameter": [ + { + "$Name": "input", + "$Type": "JSON.JSON", + "$Nullable": true, + "@Core.Description": "JSON input" + }, + { + "$Name": "path", + "$Type": "JSON.Path", + "$Nullable": true, + "@Core.Description": "JSONPath expression to be applied to value of `expr`" + } + ], + "$ReturnType": { + "$Type": "Edm.Boolean", + "$Nullable": true, + "@Core.Description": "Boolean value resulting from applying `path` to `input`" } } ], diff --git a/vocabularies/Org.OData.JSON.V1.md b/vocabularies/Org.OData.JSON.V1.md index 407657bb..9e1e647e 100644 --- a/vocabularies/Org.OData.JSON.V1.md +++ b/vocabularies/Org.OData.JSON.V1.md @@ -97,36 +97,59 @@ Parameter|Type|Description ### [value](./Org.OData.JSON.V1.xml#L184:~:text= +### [valueNumber](./Org.OData.JSON.V1.xml#L206:~:text= +### [valueBoolean](./Org.OData.JSON.V1.xml#L222:~:text= -## [JSON](./Org.OData.JSON.V1.xml#L214:~:text= -## [Path](./Org.OData.JSON.V1.xml#L225:~:text= + String="Query a stream value of media type `application/json`, returning a string" /> - Extracts a single OData primitive value from the `input` JSON value: + Extracts a single OData primitive value from the `input` JSON value and casts it to a string: - If `path` only consists of the root identifier followed by name and index selectors and identifies a single scalar JSON value (string, number, boolean, or `null`) within `input`, it returns the identified single value, cast to an OData primitive value (see below). - If `path` identifies multiple nodes within `input` (by using descendant, wildcard, union, array subset, or filter selectors), identifies an object or array, or does not identify any node, the function returns `null`. - If `input` is not a valid JSON value, the function returns `null`. -- If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input` (for example applying an index selector to a scalar value), the function returns `null`. - -If a single scalar JSON value is identified by `path` within `input`, the function returns that value as an OData primitive value: -- `null` is returned as `null` -- `true` or `false` are returned as the corresponding `Edm.Boolean` values -- numbers are returned as `Edm.Decimal` values with unspecified precision and floating scale -- strings are returned as `Edm.String` values - +- If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input` (for example applying an index selector to a scalar value), the function returns `null`. @@ -207,7 +200,39 @@ If a single scalar JSON value is identified by `path` within `input`, the functi + String="String value resulting from applying `path` to `input`" /> + + + + + + Like [`value`](#value), but casts the extracted value to an `Edm.Decimal` with unspecified precision and floating scale. + Returns null if that cast fails. + + + + + + + + + + + + + + + Like [`value`](#value), but casts the extracted value to an `Edm.Boolean`. + Returns null if that cast fails. + + + + + + + + + From 269ac5736d678038aafea163ab5374d77bfafba6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20Thei=C3=9Fen?= Date: Thu, 4 Apr 2024 12:12:08 +0200 Subject: [PATCH 26/31] Example for valueNumber --- vocabularies/Org.OData.JSON.V1.json | 2 +- vocabularies/Org.OData.JSON.V1.md | 2 +- vocabularies/Org.OData.JSON.V1.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/vocabularies/Org.OData.JSON.V1.json b/vocabularies/Org.OData.JSON.V1.json index 8629b950..d5b0d7cc 100644 --- a/vocabularies/Org.OData.JSON.V1.json +++ b/vocabularies/Org.OData.JSON.V1.json @@ -13,7 +13,7 @@ "Org.OData.JSON.V1": { "$Alias": "JSON", "@Core.Description": "Terms, types, and functions for JSON data", - "@Core.LongDescription": "OData [stream properties](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ManagingStreamProperties) allow embedding data of arbitrary media types,\nand the OData JSON format allows [direct embedding of JSON data](https://docs.oasis-open.org/odata/odata-json-format/v4.01/odata-json-format-v4.01.html#sec_StreamProperty) in request and response payloads.\n\nThis vocabulary defines a convenience [type for JSON data](#JSON) as well as a term for referencing a [JSON Schema](#Schema) describing the structure of the JSON data.\n\nIn addition it defines two functions for [querying](#query) JSON data and using a [primitive value](#value) extracted from JSON data in common expressions, for example in `$filter`, `$orderby`, or `$compute`.\n\n**Example**\n\nThe `Employees` entity set has a JSON data property `resume`:\n```json\n\"container\": {\n \"$Kind\": \"EntityContainer\",\n \"Employees\": { \"$Collection\": true, \"$Type\": \"this.Employee\" }\n},\n\"Employee\": {\n \"$Kind\": \"EntityType\",\n \"$Key\": [\"empid\"],\n \"empid\": { \"$Type\": \"Edm.Int32\" },\n \"resume\": { \"$Type\": \"JSON.JSON\", \"$Nullable\": true }\n}\n```\n\nOne of its entities has a `resume` value of\n```json\n{ \n \"ssn\": \"1234\", \n \"lastname\": \"Doe\", \n \"address\": {\n \"zipcode\": \"10022\", \n \"street\": \"ABC st\"\n },\n \"experience\": \"excellent\"\n}\n```\n\nThis allows to filter and sort by values in that resume, and extract parts of the resume as a dynamic JSON data property\n```http\nGET http://www.example.com/mycompany/Employees\n ?$filter=resume/JSON.value(path='$.lastname') eq 'Doe'\n &$orderby=resume/JSON.value(path='$.experience')\n &$compute=resume/JSON.query(path='$.address') as address\n &$expand=address\n```\nreceiving\n```json\n{ \n \"@odata.context\": \"$metadata#Employees\", \n \"value\": [ \n {\n \"empid\": 4711,\n \"address\": {\n \"zipcode\": \"10022\", \n \"street\": \"ABC st\"\n }\n },\n ...\n ]\n}\n```\n ", + "@Core.LongDescription": "OData [stream properties](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ManagingStreamProperties) allow embedding data of arbitrary media types,\nand the OData JSON format allows [direct embedding of JSON data](https://docs.oasis-open.org/odata/odata-json-format/v4.01/odata-json-format-v4.01.html#sec_StreamProperty) in request and response payloads.\n\nThis vocabulary defines a convenience [type for JSON data](#JSON) as well as a term for referencing a [JSON Schema](#Schema) describing the structure of the JSON data.\n\nIn addition it defines two functions for [querying](#query) JSON data and using a [primitive value](#value) extracted from JSON data in common expressions, for example in `$filter`, `$orderby`, or `$compute`.\n\n**Example**\n\nThe `Employees` entity set has a JSON data property `resume`:\n```json\n\"container\": {\n \"$Kind\": \"EntityContainer\",\n \"Employees\": { \"$Collection\": true, \"$Type\": \"this.Employee\" }\n},\n\"Employee\": {\n \"$Kind\": \"EntityType\",\n \"$Key\": [\"empid\"],\n \"empid\": { \"$Type\": \"Edm.Int32\" },\n \"resume\": { \"$Type\": \"JSON.JSON\", \"$Nullable\": true }\n}\n```\n\nOne of its entities has a `resume` value of\n```json\n{ \n \"ssn\": \"1234\", \n \"lastname\": \"Doe\", \n \"address\": {\n \"zipcode\": \"10022\", \n \"street\": \"ABC st\"\n },\n \"experience\": \"excellent\"\n}\n```\n\nThis allows to filter and sort by values in that resume, and extract parts of the resume as a dynamic JSON data property\n```http\nGET http://www.example.com/mycompany/Employees\n ?$filter=resume/JSON.value(path='$.lastname') eq 'Doe'\n &$orderby=resume/JSON.valueNumber(path='$.experience')\n &$compute=resume/JSON.query(path='$.address') as address\n &$expand=address\n```\nreceiving\n```json\n{ \n \"@odata.context\": \"$metadata#Employees\", \n \"value\": [ \n {\n \"empid\": 4711,\n \"address\": {\n \"zipcode\": \"10022\", \n \"street\": \"ABC st\"\n }\n },\n ...\n ]\n}\n```\n ", "@Core.Links": [ { "rel": "alternate", diff --git a/vocabularies/Org.OData.JSON.V1.md b/vocabularies/Org.OData.JSON.V1.md index 9e1e647e..8ac2cc56 100644 --- a/vocabularies/Org.OData.JSON.V1.md +++ b/vocabularies/Org.OData.JSON.V1.md @@ -43,7 +43,7 @@ This allows to filter and sort by values in that resume, and extract parts of th ```http GET http://www.example.com/mycompany/Employees ?$filter=resume/JSON.value(path='$.lastname') eq 'Doe' - &$orderby=resume/JSON.value(path='$.experience') + &$orderby=resume/JSON.valueNumber(path='$.experience') &$compute=resume/JSON.query(path='$.address') as address &$expand=address ``` diff --git a/vocabularies/Org.OData.JSON.V1.xml b/vocabularies/Org.OData.JSON.V1.xml index d796aa65..bdb4c1d8 100644 --- a/vocabularies/Org.OData.JSON.V1.xml +++ b/vocabularies/Org.OData.JSON.V1.xml @@ -104,7 +104,7 @@ This allows to filter and sort by values in that resume, and extract parts of th ```http GET http://www.example.com/mycompany/Employees ?$filter=resume/JSON.value(path='$.lastname') eq 'Doe' - &$orderby=resume/JSON.value(path='$.experience') + &$orderby=resume/JSON.valueNumber(path='$.experience') &$compute=resume/JSON.query(path='$.address') as address &$expand=address ``` From 882237a61b465aee7034acf37db762eb809720d1 Mon Sep 17 00:00:00 2001 From: Ralf Handl Date: Thu, 4 Apr 2024 13:02:42 +0200 Subject: [PATCH 27/31] Apply suggestions from code review --- vocabularies/Org.OData.JSON.V1.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vocabularies/Org.OData.JSON.V1.xml b/vocabularies/Org.OData.JSON.V1.xml index bdb4c1d8..b70435de 100644 --- a/vocabularies/Org.OData.JSON.V1.xml +++ b/vocabularies/Org.OData.JSON.V1.xml @@ -186,7 +186,7 @@ receiving String="Query a stream value of media type `application/json`, returning a string" /> Extracts a single OData primitive value from the `input` JSON value and casts it to a string: -- If `path` only consists of the root identifier followed by name and index selectors and identifies a single scalar JSON value (string, number, boolean, or `null`) within `input`, it returns the identified single value, cast to an OData primitive value (see below). +- If `path` only consists of the root identifier followed by name and index selectors and identifies a single scalar JSON value (string, number, boolean, or `null`) within `input`, it returns the identified single value, cast to a string. - If `path` identifies multiple nodes within `input` (by using descendant, wildcard, union, array subset, or filter selectors), identifies an object or array, or does not identify any node, the function returns `null`. - If `input` is not a valid JSON value, the function returns `null`. - If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input` (for example applying an index selector to a scalar value), the function returns `null`. @@ -198,7 +198,7 @@ receiving - + From f581770a86e7cd4ab41109a9072348e3039cb417 Mon Sep 17 00:00:00 2001 From: Ralf Handl Date: Thu, 4 Apr 2024 13:05:08 +0200 Subject: [PATCH 28/31] Rebuilt --- vocabularies/Org.OData.JSON.V1.json | 3 +- vocabularies/Org.OData.JSON.V1.md | 40 +++++++++++++------------- vocabularies/Org.OData.JSON.V1.xml | 44 ++++++++++------------------- 3 files changed, 36 insertions(+), 51 deletions(-) diff --git a/vocabularies/Org.OData.JSON.V1.json b/vocabularies/Org.OData.JSON.V1.json index d5b0d7cc..e0fbb4b9 100644 --- a/vocabularies/Org.OData.JSON.V1.json +++ b/vocabularies/Org.OData.JSON.V1.json @@ -76,7 +76,7 @@ "$Kind": "Function", "$IsBound": true, "@Core.Description": "Query a stream value of media type `application/json`, returning a string", - "@Core.LongDescription": "Extracts a single OData primitive value from the `input` JSON value and casts it to a string:\n- If `path` only consists of the root identifier followed by name and index selectors and identifies a single scalar JSON value (string, number, boolean, or `null`) within `input`, it returns the identified single value, cast to an OData primitive value (see below).\n- If `path` identifies multiple nodes within `input` (by using descendant, wildcard, union, array subset, or filter selectors), identifies an object or array, or does not identify any node, the function returns `null`.\n- If `input` is not a valid JSON value, the function returns `null`.\n- If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input` (for example applying an index selector to a scalar value), the function returns `null`.", + "@Core.LongDescription": "Extracts a single OData primitive value from the `input` JSON value and casts it to a string:\n- If `path` only consists of the root identifier followed by name and index selectors and identifies a single scalar JSON value (string, number, boolean, or `null`) within `input`, it returns the identified single value, cast to a string.\n- If `path` identifies multiple nodes within `input` (by using descendant, wildcard, union, array subset, or filter selectors), identifies an object or array, or does not identify any node, the function returns `null`.\n- If `input` is not a valid JSON value, the function returns `null`.\n- If `path` is `null`, not a valid [JSONPath expression](#Path), or does not match the structure of `input` (for example applying an index selector to a scalar value), the function returns `null`.", "$Parameter": [ { "$Name": "input", @@ -92,7 +92,6 @@ } ], "$ReturnType": { - "$Type": "Edm.PrimitiveType", "$Nullable": true, "@Core.Description": "String value resulting from applying `path` to `input`" } diff --git a/vocabularies/Org.OData.JSON.V1.md b/vocabularies/Org.OData.JSON.V1.md index 8ac2cc56..9e22ed41 100644 --- a/vocabularies/Org.OData.JSON.V1.md +++ b/vocabularies/Org.OData.JSON.V1.md @@ -70,13 +70,13 @@ receiving Term|Type|Description :---|:---|:---------- -[Schema](./Org.OData.JSON.V1.xml#L151:~:text=The JSON Schema for JSON values of the annotated media entity type, property, parameter, return type, term, or type definition
The schema can be a reference, i.e. `{"$ref":"url/of/schemafile#/path/to/schema/within/schemafile"}` +[Schema](./Org.OData.JSON.V1.xml#L137:~:text=The JSON Schema for JSON values of the annotated media entity type, property, parameter, return type, term, or type definition
The schema can be a reference, i.e. `{"$ref":"url/of/schemafile#/path/to/schema/within/schemafile"}` ## Functions -### [query](./Org.OData.JSON.V1.xml#L160:~:text= -### [value](./Org.OData.JSON.V1.xml#L184:~:text= -### [valueNumber](./Org.OData.JSON.V1.xml#L206:~:text= -### [valueBoolean](./Org.OData.JSON.V1.xml#L222:~:text= -## [JSON](./Org.OData.JSON.V1.xml#L239:~:text= -## [Path](./Org.OData.JSON.V1.xml#L250:~:text= From b1276f0e11d54d3fa72869b07b24fe1c829c68ab Mon Sep 17 00:00:00 2001 From: Ralf Handl Date: Thu, 4 Apr 2024 13:06:08 +0200 Subject: [PATCH 29/31] Formatting --- vocabularies/Org.OData.JSON.V1.md | 38 +++++++++++++++--------------- vocabularies/Org.OData.JSON.V1.xml | 6 ++--- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/vocabularies/Org.OData.JSON.V1.md b/vocabularies/Org.OData.JSON.V1.md index 9e22ed41..6bff6e19 100644 --- a/vocabularies/Org.OData.JSON.V1.md +++ b/vocabularies/Org.OData.JSON.V1.md @@ -70,13 +70,13 @@ receiving Term|Type|Description :---|:---|:---------- -[Schema](./Org.OData.JSON.V1.xml#L137:~:text=The JSON Schema for JSON values of the annotated media entity type, property, parameter, return type, term, or type definition
The schema can be a reference, i.e. `{"$ref":"url/of/schemafile#/path/to/schema/within/schemafile"}` +[Schema](./Org.OData.JSON.V1.xml#L135:~:text=The JSON Schema for JSON values of the annotated media entity type, property, parameter, return type, term, or type definition
The schema can be a reference, i.e. `{"$ref":"url/of/schemafile#/path/to/schema/within/schemafile"}` ## Functions -### [query](./Org.OData.JSON.V1.xml#L146:~:text= -### [value](./Org.OData.JSON.V1.xml#L170:~:text= -### [valueNumber](./Org.OData.JSON.V1.xml#L192:~:text= -### [valueBoolean](./Org.OData.JSON.V1.xml#L208:~:text= -## [JSON](./Org.OData.JSON.V1.xml#L225:~:text= -## [Path](./Org.OData.JSON.V1.xml#L236:~:text= - + - + Terms, types, and functions for JSON data From f23290047d329bee5a6c396a6ec35dd6b7c7dae2 Mon Sep 17 00:00:00 2001 From: Ralf Handl Date: Fri, 12 Apr 2024 11:35:17 +0200 Subject: [PATCH 30/31] Revert unintended line breaks --- vocabularies/Org.OData.JSON.V1.md | 38 +++++++++++++++--------------- vocabularies/Org.OData.JSON.V1.xml | 21 ++++++----------- 2 files changed, 26 insertions(+), 33 deletions(-) diff --git a/vocabularies/Org.OData.JSON.V1.md b/vocabularies/Org.OData.JSON.V1.md index 6bff6e19..f1f8a667 100644 --- a/vocabularies/Org.OData.JSON.V1.md +++ b/vocabularies/Org.OData.JSON.V1.md @@ -70,13 +70,13 @@ receiving Term|Type|Description :---|:---|:---------- -[Schema](./Org.OData.JSON.V1.xml#L135:~:text=The JSON Schema for JSON values of the annotated media entity type, property, parameter, return type, term, or type definition
The schema can be a reference, i.e. `{"$ref":"url/of/schemafile#/path/to/schema/within/schemafile"}` +[Schema](./Org.OData.JSON.V1.xml#L131:~:text=The JSON Schema for JSON values of the annotated media entity type, property, parameter, return type, term, or type definition
The schema can be a reference, i.e. `{"$ref":"url/of/schemafile#/path/to/schema/within/schemafile"}` ## Functions -### [query](./Org.OData.JSON.V1.xml#L144:~:text= -### [value](./Org.OData.JSON.V1.xml#L168:~:text= -### [valueNumber](./Org.OData.JSON.V1.xml#L190:~:text= -### [valueBoolean](./Org.OData.JSON.V1.xml#L206:~:text= -## [JSON](./Org.OData.JSON.V1.xml#L223:~:text= -## [Path](./Org.OData.JSON.V1.xml#L234:~:text= - + - + - +
- + - + The schema can be a reference, i.e. `{"$ref":"url/of/schemafile#/path/to/schema/within/schemafile"}` - + Extracts a JSON value, such as an array, object, or a JSON scalar value (string, number, boolean, or `null`) from the `input` JSON value: - If `path` only consists of the root identifier followed by name and index selectors, it returns the identified single node within `input`, or `null` if no node is identified. @@ -166,8 +160,7 @@ receiving - + Extracts a single OData primitive value from the `input` JSON value and casts it to a string: - If `path` only consists of the root identifier followed by name and index selectors and identifies a single scalar JSON value (string, number, boolean, or `null`) within `input`, it returns the identified single value, cast to a string. From 38c482779166cc249d7459243792c8df79cf842b Mon Sep 17 00:00:00 2001 From: D024504 Date: Thu, 18 Apr 2024 09:21:20 +0200 Subject: [PATCH 31/31] Reference example, don't copy it --- vocabularies/Org.OData.JSON.V1.json | 2 +- vocabularies/Org.OData.JSON.V1.md | 52 +++++++++++------------------ vocabularies/Org.OData.JSON.V1.xml | 14 +------- 3 files changed, 22 insertions(+), 46 deletions(-) diff --git a/vocabularies/Org.OData.JSON.V1.json b/vocabularies/Org.OData.JSON.V1.json index e0fbb4b9..953b52c6 100644 --- a/vocabularies/Org.OData.JSON.V1.json +++ b/vocabularies/Org.OData.JSON.V1.json @@ -13,7 +13,7 @@ "Org.OData.JSON.V1": { "$Alias": "JSON", "@Core.Description": "Terms, types, and functions for JSON data", - "@Core.LongDescription": "OData [stream properties](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ManagingStreamProperties) allow embedding data of arbitrary media types,\nand the OData JSON format allows [direct embedding of JSON data](https://docs.oasis-open.org/odata/odata-json-format/v4.01/odata-json-format-v4.01.html#sec_StreamProperty) in request and response payloads.\n\nThis vocabulary defines a convenience [type for JSON data](#JSON) as well as a term for referencing a [JSON Schema](#Schema) describing the structure of the JSON data.\n\nIn addition it defines two functions for [querying](#query) JSON data and using a [primitive value](#value) extracted from JSON data in common expressions, for example in `$filter`, `$orderby`, or `$compute`.\n\n**Example**\n\nThe `Employees` entity set has a JSON data property `resume`:\n```json\n\"container\": {\n \"$Kind\": \"EntityContainer\",\n \"Employees\": { \"$Collection\": true, \"$Type\": \"this.Employee\" }\n},\n\"Employee\": {\n \"$Kind\": \"EntityType\",\n \"$Key\": [\"empid\"],\n \"empid\": { \"$Type\": \"Edm.Int32\" },\n \"resume\": { \"$Type\": \"JSON.JSON\", \"$Nullable\": true }\n}\n```\n\nOne of its entities has a `resume` value of\n```json\n{ \n \"ssn\": \"1234\", \n \"lastname\": \"Doe\", \n \"address\": {\n \"zipcode\": \"10022\", \n \"street\": \"ABC st\"\n },\n \"experience\": \"excellent\"\n}\n```\n\nThis allows to filter and sort by values in that resume, and extract parts of the resume as a dynamic JSON data property\n```http\nGET http://www.example.com/mycompany/Employees\n ?$filter=resume/JSON.value(path='$.lastname') eq 'Doe'\n &$orderby=resume/JSON.valueNumber(path='$.experience')\n &$compute=resume/JSON.query(path='$.address') as address\n &$expand=address\n```\nreceiving\n```json\n{ \n \"@odata.context\": \"$metadata#Employees\", \n \"value\": [ \n {\n \"empid\": 4711,\n \"address\": {\n \"zipcode\": \"10022\", \n \"street\": \"ABC st\"\n }\n },\n ...\n ]\n}\n```\n ", + "@Core.LongDescription": "OData [stream properties](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ManagingStreamProperties) allow embedding data of arbitrary media types,\nand the OData JSON format allows [direct embedding of JSON data](https://docs.oasis-open.org/odata/odata-json-format/v4.01/odata-json-format-v4.01.html#sec_StreamProperty) in request and response payloads.\n\nThis vocabulary defines a convenience [type for JSON data](#JSON) as well as a term for referencing a [JSON Schema](#Schema) describing the structure of the JSON data.\n\nIn addition it defines two functions for [querying](#query) JSON data and using a [primitive value](#value) extracted from JSON data in common expressions, for example in `$filter`, `$orderby`, or `$compute`.\n\n**Example**\n\nThe `Employees` entity set has a JSON data property `resume` (see [CSDL JSON](../examples/Org.OData.JSON.V1.Schema-sample.json) or [CSDL XML](../examples/Org.OData.JSON.V1.Schema-sample.xml)).\n\nOne of its entities has a `resume` value of\n```json\n{ \n \"ssn\": \"1234\", \n \"lastname\": \"Doe\", \n \"address\": {\n \"zipcode\": \"10022\", \n \"street\": \"ABC st\"\n },\n \"experience\": \"excellent\"\n}\n```\n\nThis allows to filter and sort by values in that resume, and extract parts of the resume as a dynamic JSON data property\n```http\nGET http://www.example.com/mycompany/Employees\n ?$filter=resume/JSON.value(path='$.lastname') eq 'Doe'\n &$orderby=resume/JSON.valueNumber(path='$.experience')\n &$compute=resume/JSON.query(path='$.address') as address\n &$expand=address\n```\nreceiving\n```json\n{ \n \"@odata.context\": \"$metadata#Employees\", \n \"value\": [ \n {\n \"empid\": 4711,\n \"address\": {\n \"zipcode\": \"10022\", \n \"street\": \"ABC st\"\n }\n },\n ...\n ]\n}\n```\n ", "@Core.Links": [ { "rel": "alternate", diff --git a/vocabularies/Org.OData.JSON.V1.md b/vocabularies/Org.OData.JSON.V1.md index f1f8a667..ddf60902 100644 --- a/vocabularies/Org.OData.JSON.V1.md +++ b/vocabularies/Org.OData.JSON.V1.md @@ -12,19 +12,7 @@ In addition it defines two functions for [querying](#query) JSON data and using **Example** -The `Employees` entity set has a JSON data property `resume`: -```json -"container": { - "$Kind": "EntityContainer", - "Employees": { "$Collection": true, "$Type": "this.Employee" } -}, -"Employee": { - "$Kind": "EntityType", - "$Key": ["empid"], - "empid": { "$Type": "Edm.Int32" }, - "resume": { "$Type": "JSON.JSON", "$Nullable": true } -} -``` +The `Employees` entity set has a JSON data property `resume` (see [CSDL JSON](../examples/Org.OData.JSON.V1.Schema-sample.json) or [CSDL XML](../examples/Org.OData.JSON.V1.Schema-sample.xml)). One of its entities has a `resume` value of ```json @@ -70,13 +58,13 @@ receiving Term|Type|Description :---|:---|:---------- -[Schema](./Org.OData.JSON.V1.xml#L131:~:text=The JSON Schema for JSON values of the annotated media entity type, property, parameter, return type, term, or type definition
The schema can be a reference, i.e. `{"$ref":"url/of/schemafile#/path/to/schema/within/schemafile"}` +[Schema](./Org.OData.JSON.V1.xml#L119:~:text=The JSON Schema for JSON values of the annotated media entity type, property, parameter, return type, term, or type definition
The schema can be a reference, i.e. `{"$ref":"url/of/schemafile#/path/to/schema/within/schemafile"}` ## Functions -### [query](./Org.OData.JSON.V1.xml#L139:~:text= -### [value](./Org.OData.JSON.V1.xml#L162:~:text= -### [valueNumber](./Org.OData.JSON.V1.xml#L183:~:text= -### [valueBoolean](./Org.OData.JSON.V1.xml#L199:~:text= -## [JSON](./Org.OData.JSON.V1.xml#L216:~:text= -## [Path](./Org.OData.JSON.V1.xml#L227:~:text=