JsonDOM 1.0.7
dotnet add package JsonDOM --version 1.0.7
NuGet\Install-Package JsonDOM -Version 1.0.7
<PackageReference Include="JsonDOM" Version="1.0.7" />
<PackageVersion Include="JsonDOM" Version="1.0.7" />
<PackageReference Include="JsonDOM" />
paket add JsonDOM --version 1.0.7
#r "nuget: JsonDOM, 1.0.7"
#:package JsonDOM@1.0.7
#addin nuget:?package=JsonDOM&version=1.0.7
#tool nuget:?package=JsonDOM&version=1.0.7
This README file is merely a copy of the home page from the full JsonDOM assembly documentation which is available on GitHub at https://m-brooks.github.io/JsonDOM-docs.
JsonDOM
JsonDOM is a simple-to-use and fast-acting .Net Standard 2.0 assembly for processing JSON content. Its performance is a side-effect of its simplicity.
.Net Standard 2.0 was chosen for maximum compatibility - this can be consumed by .Net Framework (4.7.2 onwards), .Net Core, and .Net 5+ applications. It is available as a NuGet package from nuget.org.
Re the nomenclature, although both JSON (JavaScript Object Notation) and DOM (Document Object Model) are usually capitalised, I have chosen to use "Json" throughout in order to assist the camel-casing of various identifiers. Please bear with me on this - I hope you'll find in the end that on the whole it works. And in case you're wondering, I have left "DOM" capitalised because it isn't actually used as part of any identifier other than the assembly's filename; since it's a common term, I preferred to leave it as is - "JsonDOM" to my mind makes it clear that this is a DOM for JSON.
The namespace within which all types are defined is "MichaelBrooks.UK.Json".
Within the online reference pages you will see a link within each page's' Remarks section to "Online page". This is actually a convenience for developers working in Visual Studio, as it allows them to jump straight to the online documentation for a particular type or member (F1 only works with Microsoft documentation).
Please report any issues with the assembly or the documentation via the issues list https://github.com/m-brooks/JsonDOM-docs/issues on the GitHub repository for this documentation.
Overview
The typical use case for which this was developed (note that I am not suggesting that this is the only possible use case) is where your code needs to process JSON data that it has received, and optionally to modify the data (or create anew) and send it on its way to the next consumer. This differs from the use case that other JSON-related assemblies are typically designed to address, which is to serialise .Net objects to JSON and deserialise back again to known .Net objects. JsonDOM allows you to discover the structure of the JSON data that you are processing and to navigate it without needing to know in advance what .Net types it should be deserialised to.
JsonDOM works with all legal JSON. As an example, the following data (shown here as XML):
<Samples>
<Sample>45.3</Sample>
<Sample>73.5</Sample>
</Samples>
might typically be represented in JSON as:
{
"Samples" : [ 45.3, 73.5 ]
}
but could alternatively be represented by the following equally valid JSON:
{
"Samples" : {
"Sample" : 45.3,
"Sample" : 73.5
}
}
Unlike some other JSON-related libraries, JsonDOM will handle both of these options with equal ease.
Data types
The assembly exposes just two main classes (JsonNode and JsonParser) supported by
three new exception classes (JsonNode.DuplicateSiblingNameException,
JsonNode.MemberNotFoundException and JsonNodeList.DuplicateItemException) and
two enumerations (JsonNode.UnexpectedDuplicateSiblingReaction and JsonValueType).
These types all reside within the MichaelBrooks.UK.Json namespace.
JsonNode objects are arranged as a hierarchical document object model (DOM) that
represents a JSON document. They can be so arranged explicitly or as a result of
parsing a JSON document via JsonParser. A DOM can be serialised to a JSON
string with various formatting options.
JsonParser is a static class whose sole purpose is to take a JSON string and parse
it into a DOM comprising a hierarchy of JsonNode objects.
Consuming JSON
This assembly currently only consumes JSON from a string. You do so via the
JsonParser static class, by calling one of its ParseJson methods, passing in
the string that contains the JSON to be consumed. This method also accepts an
optional parameter which determines a nuance of navigation - explained further below.
The ParseJson method either returns a DOM (Document Object Model) if the JSON is
valid, or throws an exception if it isn't. The DOM is a hierarchy of JsonNode
objects. Each JsonNode has five properties:
JsonName- null for the root of the DOM.JsonValueType- which of the seven defined JSON data types the node represents (object, array, string, number, true, false, null).JsonValue- not always populated; see reference documentation for full details.Parent- null when this is the root node, otherwise references the parent node (which will be either of type object or array).Children- a list of members (if this node represents an object) or elements (if this node represents an array), or null.
Navigation
There are two mechanisms for navigating a DOM, which are covered below. If you don't know the structure of the JSON that you are processing, your only choice is the first of these.
The first is to use the
ParentandChildrenproperties of the nodes to navigate up and down the hierarchy, examining theJsonNameandJsonValueTypefor each node that you discover, before deciding where to go next. Note that the root node of the DOM has a nullParentproperty, and that only nodes representing objects or arrays (which you can identify by checking theJsonValueTypeproperty) will have a non-null Children property. If the object or array is empty, theChildrenproperty will be an empty list rather than null; otherwise it will contain one member for each member of the object or element of the array.If you know the structure of the JSON, you can quickly navigate using a bracket-based mechanism whereby within each pair of brackets you specify either the zero-based index of an array element or the name of an object member. The details of each of these are as follows:
[zero-based index] (see
Item[Int32]) - Works only with arrays. The usual rules of indexing apply, i.e. the index must be within the bounds of theChildrenlist.[name] (see
Item[String]) - Works only with objects. The name must match one of the members of the object, otherwise aJsonNode.MemberNotFoundExceptionis thrown. If multiple objects with the same name exist as siblings, the behaviour depends on the value of the optionalJsonNode.UnexpectedDuplicateSiblingReactionparameter passed to theParseJsonmethod when the DOM was created by parsing a JSON string (seeParseJson(String, JsonNode.UnexpectedDuplicateSiblingReaction)), or the optional parameter (same type) passed to the constructor of theJsonNodeclass when the parent node was created explicitly (seeJsonNode(JsonNode, JsonNode.UnexpectedDuplicateSiblingReaction)).
So for example, consider that you have a DOM that represents the JSON shown below:
{ "Sample type" : "Depths", "Sample values" : [ 45.3, 73.5 ] }You could navigate to the second value by using the following C# code:
JsonNode secondValue = dom["Sample values"][1];Note
This is me providing a degree of support for Stefan Goessner's JSONPath syntax, which is a widely used syntax for navigating JSON. However, I have only implemented the subset of JSONPath that I could do without too much effort (namely the bracket notation), so this is not a full implementation of JSONPath but it does allow you to navigate a DOM using a familiar syntax if you already know the structure of the JSON that you are processing.
For those who are familiar with XPath but unfamiliar with JSONPath, be aware that whereas XPath correctly recognises and accounts for the fact that an XML document can have multiple sibling elements with the same name, JSONPath fails to take account of the fact that a JSON object can also legally have multiple sibling members with the same name. When the IETF formed a working group to standardise JSONPath, they were aware of this shortcoming, but rather than attempt to address it they instead defined it as out of scope - see section 1.3 of RFC9535. The above-mentioned optional parameters that allow you to specify how you want JsonDOM to react when it encounters multiple sibling members with the same name are my approach to addressing this.
Creating, modifying, and outputting JSON
Once you have a DOM, you can modify it by adding, removing, or replacing nodes.
You can also modify the JsonName and/or JsonValue of any node, but there are
constraints upon changing the JsonValueType property (see the reference
documentation for details).
Also, you can create an entire DOM from scratch by instantiating JsonNode objects
and arranging them in a hierarchy.
Caution
When explicitly instantiating nodes within a DOM, you have the option of specifying how you want each node to react if it later encounters multiple sibling members with the same name when being navigated via the name-based index property (see above). Although it's legal for you to configure different nodes to react differently, in most scenarios this is likely to be a source of confusion and bugs, so I recommend that you choose one reaction and apply it consistently across all nodes in the DOM.
Once you have created the DOM, you can generate a JSON document as a string
(using various formatting options) from any node, whereby that node is treated
as the root of the JSON document to be generated. This is achieved via the
Serialise methods.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.