以递归方式遍历 jsondocument
Itereate through a jsondocument in a recursive way
我需要遍历 Jsondocument 并根据我遇到的 JsonValueKind 执行某种检查。
我尝试以这种方式进行验证检查
public bool Dec(JsonElement Element)
{
var ElementEnumeratable = Element.EnumerateObject();
foreach (var Elm in ElementEnumeratable )
{
string name = Elm.Name;
switch (Elm.Value.ValueKind)
{
case JsonValueKind.Array:
var jArray = Elm.Value;
return Dec(jArray);
case JsonValueKind.String:
string jString = Elm.Value.GetString();
break;
case JsonValueKind.Number:
int jNumber = Elm.Value.GetInt32();
break;
}
}
return true;
}
这里的问题是 Elm
有 ValueKind
数组 - 我无法将它传递给 Dec
似乎以 valuekind 作为数组的 JsonElement 无法转换为 EnumerateObject?
来这里做什么?
我认为你在错误的地方进行切换。如果用数组调用 Dec()
,它仍然会调用 EnumerateObject()
。它需要为数组调用 EnumerateArray()
。
据我了解,如果 ValueKind
是 JsonValueKind.Array
那么您需要使用 EnumerateArray()
迭代数组,这样您将拥有 JElement
并调用 Dec
foreach 元素来验证它们中的每一个,像这样:
public static bool Dec(JsonElement Element)
{
var ElementEnumeratable = Element.EnumerateObject();
foreach (var Elm in ElementEnumeratable)
{
string name = Elm.Name;
switch (Elm.Value.ValueKind)
{
case JsonValueKind.Array:
var jArray = Elm.Value;
foreach (var item in jArray.EnumerateArray())
{
Dec(item);
}
break;
case JsonValueKind.String:
string jString = Elm.Value.GetString();
break;
case JsonValueKind.Number:
int jNumber = Elm.Value.GetInt32();
break;
}
}
return true;
}
我这样更新了建议的代码:
public static JsonData Decode(JsonElement jsonElement, string elementName = "Root", JsonData parent = null)
{
JsonData result = null;
string jsonString = null;
double jsonDouble = 0;
bool jsonBool = false;
JsonElement jsonArray;
result = new JsonData(elementName, parent);
switch (jsonElement.ValueKind)
{
case JsonValueKind.Undefined:
break;
case JsonValueKind.Object:
ObjectEnumerator objectEnumerator = jsonElement.EnumerateObject();
foreach (var item in objectEnumerator)
{
string name = item.Name;
switch (item.Value.ValueKind)
{
case JsonValueKind.Undefined:
break;
case JsonValueKind.Object:
JsonElement element = (JsonElement)item.Value;
result.Childrens.Add(Decode(element, name, result));
break;
case JsonValueKind.Array:
jsonArray = item.Value;
foreach (var arrayItem in jsonArray.EnumerateArray())
{
result.Childrens.Add(Decode(arrayItem, name, result));
}
break;
case JsonValueKind.String:
jsonString = item.Value.GetString();
result.Items.Add(name, jsonString);
break;
case JsonValueKind.Number:
jsonDouble = item.Value.GetDouble();
result.Items.Add(name, jsonDouble);
break;
case JsonValueKind.True:
jsonBool = item.Value.GetBoolean();
result.Items.Add(name, jsonBool);
break;
case JsonValueKind.False:
jsonBool = item.Value.GetBoolean();
result.Items.Add(name, jsonBool);
break;
case JsonValueKind.Null:
result.Items.Add(name, null);
break;
default:
break;
}
}
break;
case JsonValueKind.Array:
jsonArray = jsonElement;
foreach (var arrayItem in jsonArray.EnumerateArray())
{
result.Items.Add(elementName, arrayItem);
}
break;
case JsonValueKind.String:
jsonString = jsonElement.GetString();
result.Items.Add(elementName, jsonString);
break;
case JsonValueKind.Number:
jsonDouble = jsonElement.GetDouble();
result.Items.Add(elementName, jsonDouble);
break;
case JsonValueKind.True:
jsonBool = jsonElement.GetBoolean();
result.Items.Add(elementName, jsonBool);
break;
case JsonValueKind.False:
jsonBool = jsonElement.GetBoolean();
result.Items.Add(elementName, jsonBool);
break;
case JsonValueKind.Null:
result.Items.Add(elementName, null);
break;
default:
break;
}
return result;
}
返回的class是下面的:
public class JsonData
{
public JsonData Parent { get; private set; }
public List<JsonData> Childrens { get; private set; }
public string Name { get; private set; }
public Dictionary<string, object> Items { get; private set; }
public JsonData(string name, JsonData parent = null)
{
Parent = parent;
Childrens = new List<JsonData>();
Name = name;
Items = new Dictionary<string, object>();
}
}
用法:
JsonDocument jsonDoc = null;
JsonData jsonData = null;
string json = File.ReadAllText(@"c:\jsonpath.json");
if (!string.IsNullOrEmpty(json))
{
jsonDoc = JsonDocument.Parse(json, new JsonDocumentOptions { CommentHandling = JsonCommentHandling.Skip });
if (jsonDoc != null)
{
jsonData = Decode(jsonDoc.RootElement);
}
}
if (jsonData != null)
{
JsonData financialData = jsonData.Childrens.FirstOrDefault(c => c.Name == "Financial Data");
if (financialData != null)
{
List<JsonData> transactions = financialData.Childrens.Where(c => c.Name == "Transaction history").ToList<JsonData>();
}
}
我需要遍历 Jsondocument 并根据我遇到的 JsonValueKind 执行某种检查。
我尝试以这种方式进行验证检查
public bool Dec(JsonElement Element)
{
var ElementEnumeratable = Element.EnumerateObject();
foreach (var Elm in ElementEnumeratable )
{
string name = Elm.Name;
switch (Elm.Value.ValueKind)
{
case JsonValueKind.Array:
var jArray = Elm.Value;
return Dec(jArray);
case JsonValueKind.String:
string jString = Elm.Value.GetString();
break;
case JsonValueKind.Number:
int jNumber = Elm.Value.GetInt32();
break;
}
}
return true;
}
这里的问题是 Elm
有 ValueKind
数组 - 我无法将它传递给 Dec
似乎以 valuekind 作为数组的 JsonElement 无法转换为 EnumerateObject?
来这里做什么?
我认为你在错误的地方进行切换。如果用数组调用 Dec()
,它仍然会调用 EnumerateObject()
。它需要为数组调用 EnumerateArray()
。
据我了解,如果 ValueKind
是 JsonValueKind.Array
那么您需要使用 EnumerateArray()
迭代数组,这样您将拥有 JElement
并调用 Dec
foreach 元素来验证它们中的每一个,像这样:
public static bool Dec(JsonElement Element)
{
var ElementEnumeratable = Element.EnumerateObject();
foreach (var Elm in ElementEnumeratable)
{
string name = Elm.Name;
switch (Elm.Value.ValueKind)
{
case JsonValueKind.Array:
var jArray = Elm.Value;
foreach (var item in jArray.EnumerateArray())
{
Dec(item);
}
break;
case JsonValueKind.String:
string jString = Elm.Value.GetString();
break;
case JsonValueKind.Number:
int jNumber = Elm.Value.GetInt32();
break;
}
}
return true;
}
我这样更新了建议的代码:
public static JsonData Decode(JsonElement jsonElement, string elementName = "Root", JsonData parent = null)
{
JsonData result = null;
string jsonString = null;
double jsonDouble = 0;
bool jsonBool = false;
JsonElement jsonArray;
result = new JsonData(elementName, parent);
switch (jsonElement.ValueKind)
{
case JsonValueKind.Undefined:
break;
case JsonValueKind.Object:
ObjectEnumerator objectEnumerator = jsonElement.EnumerateObject();
foreach (var item in objectEnumerator)
{
string name = item.Name;
switch (item.Value.ValueKind)
{
case JsonValueKind.Undefined:
break;
case JsonValueKind.Object:
JsonElement element = (JsonElement)item.Value;
result.Childrens.Add(Decode(element, name, result));
break;
case JsonValueKind.Array:
jsonArray = item.Value;
foreach (var arrayItem in jsonArray.EnumerateArray())
{
result.Childrens.Add(Decode(arrayItem, name, result));
}
break;
case JsonValueKind.String:
jsonString = item.Value.GetString();
result.Items.Add(name, jsonString);
break;
case JsonValueKind.Number:
jsonDouble = item.Value.GetDouble();
result.Items.Add(name, jsonDouble);
break;
case JsonValueKind.True:
jsonBool = item.Value.GetBoolean();
result.Items.Add(name, jsonBool);
break;
case JsonValueKind.False:
jsonBool = item.Value.GetBoolean();
result.Items.Add(name, jsonBool);
break;
case JsonValueKind.Null:
result.Items.Add(name, null);
break;
default:
break;
}
}
break;
case JsonValueKind.Array:
jsonArray = jsonElement;
foreach (var arrayItem in jsonArray.EnumerateArray())
{
result.Items.Add(elementName, arrayItem);
}
break;
case JsonValueKind.String:
jsonString = jsonElement.GetString();
result.Items.Add(elementName, jsonString);
break;
case JsonValueKind.Number:
jsonDouble = jsonElement.GetDouble();
result.Items.Add(elementName, jsonDouble);
break;
case JsonValueKind.True:
jsonBool = jsonElement.GetBoolean();
result.Items.Add(elementName, jsonBool);
break;
case JsonValueKind.False:
jsonBool = jsonElement.GetBoolean();
result.Items.Add(elementName, jsonBool);
break;
case JsonValueKind.Null:
result.Items.Add(elementName, null);
break;
default:
break;
}
return result;
}
返回的class是下面的:
public class JsonData
{
public JsonData Parent { get; private set; }
public List<JsonData> Childrens { get; private set; }
public string Name { get; private set; }
public Dictionary<string, object> Items { get; private set; }
public JsonData(string name, JsonData parent = null)
{
Parent = parent;
Childrens = new List<JsonData>();
Name = name;
Items = new Dictionary<string, object>();
}
}
用法:
JsonDocument jsonDoc = null;
JsonData jsonData = null;
string json = File.ReadAllText(@"c:\jsonpath.json");
if (!string.IsNullOrEmpty(json))
{
jsonDoc = JsonDocument.Parse(json, new JsonDocumentOptions { CommentHandling = JsonCommentHandling.Skip });
if (jsonDoc != null)
{
jsonData = Decode(jsonDoc.RootElement);
}
}
if (jsonData != null)
{
JsonData financialData = jsonData.Childrens.FirstOrDefault(c => c.Name == "Financial Data");
if (financialData != null)
{
List<JsonData> transactions = financialData.Childrens.Where(c => c.Name == "Transaction history").ToList<JsonData>();
}
}