Functionality of this library includes:
Enumerate over json elements.
Useful for fetching selected parts of the json
Rely on path convention:
json.ToEnumerable(/path convention/);
Json
{ "friends": [ { "name": "Yaron", "id": 1 }, { "name": "Aviad", "id": 2 } ] }
Sample: `friends.[].name` or `friends.*.name`
var items = source.ToEnumerable("friends.[].name");OR
var items = source.ToEnumerable("friends.*.name");RESULT
["Yaron", "Aviad"]
Sample: `friends.[0].name`
var items = source.ToEnumerable("friends.[0].name");RESULT
["Yaron"]
Sample: `friends.[0].*`
var items = source.ToEnumerable("friends.[0].*");RESULT
["Yaron",1]
See: YieldWhen_Path_Test in the source code
Yield element according to predicate and onMatch delegates.
Json
{ "projects": [ { "key": "cloud-d", "duration": 8 }, { "users": [{ "rank": { "job": 10, "relationship": { "projects": [ { "key": "cloud-d", "team": 5 }, { "key": "cloud-x", "team": 32 } ] } }, }] }
Code
TraverseInstruction Predicate(JsonElement current, IImmutableList<string> breadcrumbs) { if (breadcrumbs.Count < 4) return ToChildren; if (breadcrumbs[^4] == "relationship" && breadcrumbs[^3] == "projects" && breadcrumbs[^1] == "key") { return new TraverseInstruction(Stop, TraverseAction.Take); } return ToChildren; } var items = source.ToEnumerable(Predicate);
Reduce (or modify) a json
Json
JSON:
{ "A": 10, "B": [ { "Val": 40 }, { "Val": 20 }, { "Factor": 20 } ], "C": [0, 25, 50, 100 ], "Note": "Re-shape json" }
Code
TraverseInstruction Strategy( JsonElement e, IImmutableList<string> breadcrumbs) { if (e.ValueKind == JsonValueKind.Number) { var val = e.GetInt32(); if (val > 30) return TraverseInstruction.TakeOrReplace; return TraverseInstruction.SkipToSibling; } if (e.ValueKind == JsonValueKind.Array || e.ValueKind == JsonValueKind.Object) return TraverseInstruction.ToChildren; return TraverseInstruction.TakeOrReplace; } JsonElement target = source.Filter(Strategy);Will result in:
{ "B": [ { "Val": 40 }], "C": [ 50, 100 ], "Note": "Re-shape json" }
Path based Filter
Json
``` json { "A": 10, "B": [ { "Val": 40 }, { "Val": 20 }, { "Factor": 20 } ], "C": [0, 25, 50, 100 ], "Note": "Re-shape json" } ```
Sample: B.*.val
var target = source.Keep("B.*.val");RESULT
{"B":[{"Val":40},{"Val":20}]}
Sample: B.[]
var target = source.Keep("B.[]");RESULT
{"B":[{"Val":40},{"Val":20},{"Factor":20}]}
Sample: B.[1].val
var target = source.Keep("B.[].Factor");RESULT
{"B":[{"Factor":20}]}
Sample: B.[1].val
var target = source.Keep("B.[1].val");RESULT
{"B":[{"Val":20}]}
Remove elements from the json.
Json
{ "A": 10, "B": [ { "Val": 40 }, { "Val": 20 }, { "Factor": 20 } ], "C": [0, 25, 50, 100 ], "Note": "Re-shape json" }
Sample: B.[]
var target = source.Remove("B.[]");RESULT
{"A":10,"C":[0,25,50,100],"Note":"Re-shape json"}
Sample: B.*.val
var target = source.Remove("B.*.val");RESULT
{"A":10,"B":[{"Factor":20}],"C":[0,25,50,100],"Note":"Re-shape json"}
Sample: B.[1]
var target = source.Remove("B.[1]");RESULT
{"A":10,"B":[{"Val":40},{"Factor":20}],"C":[0,25,50,100],"Note":"Re-shape json"}
Sample: B
var target = source.Remove("B");RESULT
{"A":10,"C":[0,25,50,100],"Note":"Re-shape json"}
Sample: B.[1].val
var target = source.Remove("B.[1].val");RESULT
{"A":10,"B":[{"Val":40},{"Val":20},{"Factor":20}],"C":[0,25,50,100],"Note":"Re-shape json"}
Try to add property if missing.
Sample 1
{ "A": 0, "B": 0 }source.RootElement.TryAddProperty("C", 1);Result in:
{ "A": 0, "B": 0, "C": 1 }
Sample 2
{ "A": 0, "B": 0, "C": 0 }source.RootElement.TryAddProperty("C", 1);Result in:
{ "A": 0, "B": 0, "C": 0 }
Sample: 3
{ "A": 0, "B": 0, "C": null }var source = JsonDocument.Parse(json); source.RootElement.TryAddProperty("C", 1);Result in:
{ "A": 0, "B": 0, "C": 1 }
Unless sets the options not to ignore null
Sample: ignored null
Ignored null
var options = new JsonPropertyModificatonOpions { IgnoreNull = false }; var source = JsonDocument.Parse(json); source.RootElement.TryAddProperty("C", 1);Result in:
{ "A": 0, "B": 0, "C": null }
Sample: Changing property within a path
Changing property within a path
{ "X": { "Y": { "A": 0, "B": 0 } }, "Y": { "Q": 2 } }source.RootElement.TryAddProperty("X.Y", "C", 1);Result in:
{ "X": { "Y": { "A": 0, "B": 0, "C": 1 } }, "Y": { "Q": 2 } }
Try to get a value within a path
Json
{ "B": { "B1": ["Very", "Cool"], "B2": { "B21": { "B211": "OK" }, "B22": 22, "B23": true, "B24": 1.8, "B25": "2007-09-01T10:35:01", "B26": "2007-09-01T10:35:01+02" } } }
Sample: B.B1
source.TryGetValue(out JsonElement value, "B.B1")Result in:
["Very","Cool"]
Sample: B.B1.*
source.TryGetValue(out JsonElement value, "B.B1.*")Result in:
Very
Try to get a value within a path.
Json
{ "B": { "B1": ["Very", "Cool"], "B2": { "B21": { "B211": "OK" }, "B22": 22, "B23": true, "B24": 1.8, "B25": "2007-09-01T10:35:01", "B26": "2007-09-01T10:35:01+02" } } }
Sample: String
source.TryGetString(out JsonElement value, "B.B2.*.B211")Result in:
OK
Sample: DateTiemOffset
source.TryGetValue(out JsonElement value, "B.*.B26")Result in:
2007-09-01T10:35:01+02
Sample: Double
source.TryGetNumber(out double value, "B.B2.B24")Result in:
1.8
Merging 2 or more json. The last json will override previous on conflicts
Sample: 1
Source:
{ "A": 1 }
, Merged:{ "B": 2 }
var target = source.Merge(merged);Result in:
{"A":1,"b":2}
Sample: 2
Source:
{ "A": 1 }
, Merged:{"B":2,"C":3}
var target = source.Merge(merged);Result in:
{ "A":1, "B":2, "C":3 }
Sample:
Source:
{ "A": 1 }
, Merged1:{"B":2}
, Merged2:{"C":3}
var target = source.Merge(merged1, merged2);Result in:
{ "A":1, "B":2, "C":3 }
Sample:
Source:
{ "A": 1 }
var target = source.MergeObject(new { b = 2 });Result in:
{"A":1, "B":2}
Merging json into specific path of a source json.
The last json will override any previous one in case of a conflicts
Sample: 1
Source
{ "A": 1, "B": { "B1":[1, 2, 3] }, "C": { "D": { "X":1, "Y":2 } } }var target = source.MergeInto("C.D.X", 100);Result in:
{ "A": 1, "B": { "B1":[1, 2, 3] }, "C": { "D": { "X":100, "Y":2 } } }
Sample: 2
Source
{ "A": 1, "B": { "B1":[1, 2, 3] }, "C": { "D": { "X":1, "Y":2 } } }Merged
{ "Z": 3}var target = source.MergeInto("C.D", merged);Result in:
{ "A": 1, "B": { "B1":[1, 2, 3] }, "C": { "D": { "X":1, "Y":2, "Z": 3 } } }
Sample: 3
Source
{'A':1,'B': {'B1':1}}Merged
{'B1':3, 'C':[1,2,3]}
var target = source.MergeInto("B", merged);Result in:
{'A':1, 'B':{'B1':3, 'C':[1,2,3]}}
Sample: 4
Source
{'A':1,'B':{'B1':[1,2,3]}}var target = source.MergeInto("B.B1.[1]", 5);Result in:
{'A':1, 'B':{'B1':[1,5,3]}}
Convert .NET object into JsonElement.
var entity = new Entity(12, new BEntity("Z"));
JsonElement json = entity.ToJson();
var arr = new []{ 1, 2, 3 };
JsonElement json = arr.ToJson();
Convert JsonElement to string
JsonElement json = ...;
string compact = json.AsString();
string indented = json.AsIndentString();
string raw = json.GetRawText(); // same as json.AsIndentString();
Convert JsonElement to stream
var json = JsonDocument.Parse(JSON);
var srm = json.ToStream() as MemoryStream;
string result = Encoding.UTF8.GetString(srm.ToArray()) ;
Check the following