使用 System.Text.Json (.NET 6) 获取 JSON 的所有路径和类型
Get all path and types of a JSON with System.Text.Json (.NET 6)
我编写了以下方法来获取 JSON.NET 中 JSON 中所有键的 Path + Type
的所有组合:
public static IEnumerable<string> GetKeys(this JToken jToken)
{
var keys = new List<string>();
var jTokenKey = $"{(string.IsNullOrEmpty(jToken.Path) ? "{/ROOT/}" : jToken.Path)}-{jToken.Type}";
keys.Add(jTokenKey);
foreach (var child in jToken.Children())
{
var key = child.GetKeys();
keys.AddRange(key);
}
return keys;
}
我需要 Path + Type
的组合,用于 JSON 的所有元素。
任何人都可以帮助我获得与 System.Text.Json
相同(或相似)的结果吗?
样本:
{
"a": [{
"b": "bbb",
"c": "ccc",
"d": "ddd"
}
],
"e": "2021-12-29T14:20:21.948Z",
"f": {
"g": [{
"h": "hhh",
"i": "iii",
"j": null,
"k": true,
"l": false,
"m": "2021-12-29T14:20:21.948Z",
"n": 10
}
]
}
}
JSON.NET 结果:
$-Object
a-Property
a-Array
a[0]-Object
a[0].b-Property
a[0].b-String
a[0].c-Property
a[0].c-String
a[0].d-Property
a[0].d-String
e-Property
e-Date
f-Property
f-Object
f.g-Property
f.g-Array
f.g[0]-Object
f.g[0].h-Property
f.g[0].h-String
f.g[0].i-Property
f.g[0].i-String
f.g[0].j-Property
f.g[0].j-Null
f.g[0].k-Property
f.g[0].k-Boolean
f.g[0].l-Property
f.g[0].l-Boolean
f.g[0].m-Property
f.g[0].m-Date
f.g[0].n-Property
f.g[0].n-Integer
您可以使用 JsonDocument
API,它允许以某种类似于 Newtonsoft 的方式解析和操作 json。像这样(需要一些工作才能完全表示所需的格式):
IEnumerable<string> EnumeratePaths(JsonElement doc)
{
var queu = new Queue<(string ParentPath, JsonElement element)>();
queu.Enqueue(("", doc));
while (queu.Any())
{
var (parentPath, element) = queu.Dequeue();
switch (element.ValueKind)
{
case JsonValueKind.Object:
parentPath = parentPath == ""
? parentPath
: parentPath + ".";
foreach (var nextEl in element.EnumerateObject())
{
queu.Enqueue(($"{parentPath}{nextEl.Name}", nextEl.Value));
}
break;
case JsonValueKind.Array:
foreach (var (nextEl, i) in element.EnumerateArray().Select((jsonElement, i) => (jsonElement, i)))
{
queu.Enqueue(($"{parentPath}[{i}]", nextEl));
}
break;
case JsonValueKind.Undefined:
case JsonValueKind.String:
case JsonValueKind.Number:
case JsonValueKind.True:
case JsonValueKind.False:
case JsonValueKind.Null:
yield return parentPath;
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}
并使用:
var json = ...;
using var doc = JsonDocument.Parse(json);
var names = EnumeratePaths(doc.RootElement).ToList();
我编写了以下方法来获取 JSON.NET 中 JSON 中所有键的 Path + Type
的所有组合:
public static IEnumerable<string> GetKeys(this JToken jToken)
{
var keys = new List<string>();
var jTokenKey = $"{(string.IsNullOrEmpty(jToken.Path) ? "{/ROOT/}" : jToken.Path)}-{jToken.Type}";
keys.Add(jTokenKey);
foreach (var child in jToken.Children())
{
var key = child.GetKeys();
keys.AddRange(key);
}
return keys;
}
我需要 Path + Type
的组合,用于 JSON 的所有元素。
任何人都可以帮助我获得与 System.Text.Json
相同(或相似)的结果吗?
样本:
{
"a": [{
"b": "bbb",
"c": "ccc",
"d": "ddd"
}
],
"e": "2021-12-29T14:20:21.948Z",
"f": {
"g": [{
"h": "hhh",
"i": "iii",
"j": null,
"k": true,
"l": false,
"m": "2021-12-29T14:20:21.948Z",
"n": 10
}
]
}
}
JSON.NET 结果:
$-Object
a-Property
a-Array
a[0]-Object
a[0].b-Property
a[0].b-String
a[0].c-Property
a[0].c-String
a[0].d-Property
a[0].d-String
e-Property
e-Date
f-Property
f-Object
f.g-Property
f.g-Array
f.g[0]-Object
f.g[0].h-Property
f.g[0].h-String
f.g[0].i-Property
f.g[0].i-String
f.g[0].j-Property
f.g[0].j-Null
f.g[0].k-Property
f.g[0].k-Boolean
f.g[0].l-Property
f.g[0].l-Boolean
f.g[0].m-Property
f.g[0].m-Date
f.g[0].n-Property
f.g[0].n-Integer
您可以使用 JsonDocument
API,它允许以某种类似于 Newtonsoft 的方式解析和操作 json。像这样(需要一些工作才能完全表示所需的格式):
IEnumerable<string> EnumeratePaths(JsonElement doc)
{
var queu = new Queue<(string ParentPath, JsonElement element)>();
queu.Enqueue(("", doc));
while (queu.Any())
{
var (parentPath, element) = queu.Dequeue();
switch (element.ValueKind)
{
case JsonValueKind.Object:
parentPath = parentPath == ""
? parentPath
: parentPath + ".";
foreach (var nextEl in element.EnumerateObject())
{
queu.Enqueue(($"{parentPath}{nextEl.Name}", nextEl.Value));
}
break;
case JsonValueKind.Array:
foreach (var (nextEl, i) in element.EnumerateArray().Select((jsonElement, i) => (jsonElement, i)))
{
queu.Enqueue(($"{parentPath}[{i}]", nextEl));
}
break;
case JsonValueKind.Undefined:
case JsonValueKind.String:
case JsonValueKind.Number:
case JsonValueKind.True:
case JsonValueKind.False:
case JsonValueKind.Null:
yield return parentPath;
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}
并使用:
var json = ...;
using var doc = JsonDocument.Parse(json);
var names = EnumeratePaths(doc.RootElement).ToList();