以递归方式遍历JsonDocument



我需要遍历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;
}

这里的问题是,当ElmValueKind数组时——我无法将其传递给Dec——看起来像是将valuekind作为数组的JsonElement,无法转换为EnumerateObject

在这里该怎么办?

据我所知,如果ValueKindJsonValueKind.Array,那么您需要使用EnumerateArray()迭代数组,这样您就有了JsonElement,并在每个元素之前调用Dec来验证它们,如下所示:

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;
}

返回的类如下:

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>();
}
}

我认为你切换的地方不对。如果使用Array调用Dec(),它仍然会调用EnumerateObject()。它需要为一个数组调用EnumerateArray()

最新更新