From 850a78eb0e561e0d3a198c8c4c3ad48cb33b2d8e Mon Sep 17 00:00:00 2001 From: Greg Dennis Date: Thu, 25 Apr 2024 21:49:42 +1200 Subject: [PATCH 1/3] update schema docs --- _docs/schema/basics.md | 9 +++++---- _docs/schema/vocabs.md | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/_docs/schema/basics.md b/_docs/schema/basics.md index 2f100666..42a04f55 100644 --- a/_docs/schema/basics.md +++ b/_docs/schema/basics.md @@ -47,7 +47,7 @@ There are two options when building a schema: defining it inline using the fluen ## Serialization and Deserialization {#schema-deserialization} -*JsonSchema.Net* schemas are fully serializable. +_JsonSchema.Net_ schemas are fully serializable. ```c# var mySchema = JsonSchema.FromText(content); @@ -463,7 +463,8 @@ New formats must be registered via the `Formats.Register()` static method. This The `EvaluationOptions` class gives you a few configuration points for customizing how the evaluation process behaves. It is an instance class and can be passed into the `JsonSchema.Evaluate()` method. If no options are explicitly passed, a copy of `JsonSchemaOptions.Default` will be used. -- `EvaluateAs` - Indicates which schema version to process as. This will filter the keywords of a schema based on their support. This means that if any keyword is not supported by this version, it will be ignored. +- `EvaluateAs` - Indicates which schema version to process as. This will filter the keywords of a schema based on their support. This means that if any keyword is not supported by this version, it will be ignored. This will need to be set when you create the options. +- `SchemaRegistry` - Provides a way to register schemas only for the evaluations that use this set of options. - `EvaluateMetaSchema` - Indicates whether the schema should be evaluated against its `$schema` value (its meta-schema). This is not typically necessary. Note that the evaluation process will still attempt to resolve the meta-schema. \* - `OutputFormat` - You already read about output formats above. This is the property that controls it all. By default, a single "flag" node is returned. This also yields the fastest evaluation times as it enables certain optimizations. - `RequireFormatValidation` - Forces `format` validation. @@ -549,7 +550,7 @@ var randomString = JsonSchema.FromFile("random-string.json"); SchemaRegistry.Global.Register(new Uri("http://localhost/random-string"), randomString); ``` -Now *JsonSchema.Net* will be able to resolve the reference. +Now _JsonSchema.Net_ will be able to resolve the reference. > `JsonSchema.FromFile()` automatically sets the schema's base URI to the file path. If you intend to use file paths in your references (e.g. `file:///C:\random-string.json`), then just register the schema without passing a URI: > @@ -576,7 +577,7 @@ var referenceableJson = new JsonNodeBaseDocument(json, "http://localhost/jsondat SchemaRegistry.Global.Register(referenceableJson); var schema = new JsonSchemaBuilder() - .Ref("http://localhost/jsondata#/schema) + .Ref("http://localhost/jsondata#/schema") .Build(); ``` diff --git a/_docs/schema/vocabs.md b/_docs/schema/vocabs.md index 4fd328f6..d78d62be 100644 --- a/_docs/schema/vocabs.md +++ b/_docs/schema/vocabs.md @@ -158,7 +158,7 @@ The `maximum` keyword is basically all instance. It asks, "Is the instance a nu ```c# public KeywordConstraint GetConstraint(SchemaConstraint schemaConstraint, - IReadOnlyList localConstraints, + ReadOnlySpan localConstraints, EvaluationContext context) { return new KeywordConstraint(Name, Evaluator); @@ -218,7 +218,7 @@ More specifically to our task here, `properties` gives us a list of subschemas t ```c# public KeywordConstraint GetConstraint(SchemaConstraint schemaConstraint, - IReadOnlyList localConstraints, + ReadOnlySpan localConstraints, EvaluationContext context) { var subschemaConstraints = Properties From 2fc227a477e91d599ffe6cf09a59c3359e1f5acb Mon Sep 17 00:00:00 2001 From: Greg Dennis Date: Thu, 25 Apr 2024 22:02:53 +1200 Subject: [PATCH 2/3] update pointer docs --- _docs/pointer/basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_docs/pointer/basics.md b/_docs/pointer/basics.md index 059f3cd4..aa0ef065 100644 --- a/_docs/pointer/basics.md +++ b/_docs/pointer/basics.md @@ -50,7 +50,7 @@ It also supports a URL format, which is essentially the same thing, except that ## In code {#pointer-in-code} -The `JsonPointer` class is the model for JSON Pointer. +The `JsonPointer` struct is the model for JSON Pointer. There are three ways create pointers: From de98a5a79542aef5aa20184f7d305e669b0364d7 Mon Sep 17 00:00:00 2001 From: Greg Dennis Date: Tue, 30 Apr 2024 22:23:51 +1200 Subject: [PATCH 3/3] update with latest architecture --- _docs/pointer/basics.md | 51 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/_docs/pointer/basics.md b/_docs/pointer/basics.md index aa0ef065..baeb2aef 100644 --- a/_docs/pointer/basics.md +++ b/_docs/pointer/basics.md @@ -50,7 +50,7 @@ It also supports a URL format, which is essentially the same thing, except that ## In code {#pointer-in-code} -The `JsonPointer` struct is the model for JSON Pointer. +The `JsonPointer` class is the model for JSON Pointer. There are three ways create pointers: @@ -87,6 +87,55 @@ var success = pointer.TryEvaluate(element, out var result); > The designers of the `JsonNode` API have elected (for [reasons](https://github.com/dotnet/designs/blob/40794be63ecd8b35e9596412050a84dedd575b99/accepted/2020/serializer/WriteableDomAndDynamic.md#missing-vs-null) I [disagree](https://github.com/dotnet/runtime/issues/66948#issuecomment-1080148457) with) to consider JSON null and .Net null to be equivalent. This goes against both my personal experience building Manatee.Json and the `JsonElement` API, both of which maintain a separation between these two null concepts. Because of the unified design, it's impossible to determine whether a returned `JsonNode` value of `null` represents a value that is present but null or it is merely absent from the data. To accommodate this, the evaluation method can only support the familiar `TryParse()` signature. A return of `true` indicates the value was found, and `false` indicates it was not. In the case of a `true` return, `result` may still be null, indicating the value was found and was a JSON null. {: .prompt-info } +### Pointer math + +You can also combine and augment pointers in different ways. + +Joining two pointers together: + +```c# +var pointer1 = JsonPointer.Parse("/objects/and"); +var pointer2 = JsonPointer.Parse("/3/arrays"); +var final = pointer1.Combine(pointer2); +``` + +Appending additional segments to an existing pointer: + +```c# +var pointer = JsonPointer.Parse("/objects/and"); +var final = pointer1.Combine(3, "arrays"); +``` + +### Access pointer parts and create sub-pointers + +You can retrieve the individual segments using the indexer: + +```c# +var pointer = JsonPointer.Parse("/objects/and/3/arrays"); +var andSegment = pointer[1]; // "and" (string) +``` + +If you're using .Net 8 or higher, the indexer also supports `Range` values, so you can obtain a new pointer containing a portion of the segments. + +Get the immediate parent: + +```c# +var pointer = JsonPointer.Parse("/objects/and/3/arrays"); +var parent = pointer[..^1]; // /objects/and/3 +``` + +Or get the local pointer (imagine you've navigated to `/objects/and/` and you need the pointer relative to where you are): + +```c# +var pointer = JsonPointer.Parse("/objects/and/3/arrays"); +var local = pointer[^2..]; // /3/arrays +``` + +There are also method versions of this functionality, which are also available if you're not yet using .Net 8: `.GetAncestor(int)` and `.GetLocal()`. + +> Accessing pointers acts like accessing strings: getting segments has no allocations (like getting a `char` via the string's `int` indexer), but creating a sub-pointer _does_ allocate a new `JsonPointer` instance (like creating a substring via the string's `Range` indexer). +{: .prompt-info } + ### Building pointers using Linq expressions {#linq} When building a pointer using the `Create()` method which takes a Linq expression, there are a couple of things to be aware of.