解析复杂的 JSON:多个循环与类

本文关键字:循环 复杂 JSON | 更新日期: 2023-09-27 17:56:23

我有一个类型的 Json:

{
"JobProcessors": [
{
  "JobName": "ArchivalJob",
  "IsEnabled": true,
  "Batching": {
    "BatchSize": 0,
    "DegreeOfParallelism": -1
  },
  "Settings": {
    "ArchivalJobCollectionPageSize": 50
  }
},
{
  "JobName": "AuditLogJob",
  "IsEnabled": false,
  "Batching": {
    "BatchSize": 10,
    "DegreeOfParallelism": -1
  },
  "Settings": {}
} 
],  
"ScheduledJobs": [
{
  "JobName": "RemoteStartClientCommandJob",
  "PrimaryAction": {
    "ConnectionString": "#JobProcessorsIntegrationSBConnectionStringValue#",
     "Settings": {
      "LeadTimeInSeconds": "600",
      "MaxSrsJobCount": 25
    }
  },
  "ErrorAction": {
    "ConnectionString": "#PairedJobProcessorIntegrationSBConnectionStringValue#",
    "EntityPath": "remotestartqueue",
    "Settings": {
      "LeadTimeInSeconds": "600",
      "MaxSrsJobCount": 25
    }
  }
}
]  
}

我想检查"作业处理器"类别下的所有"作业名称"的"已启用"属性。在 C# 中,我到目前为止使用的是:

dynamic parsedJson = JsonConvert.DeserializeObject(reader.GetString(1));
foreach (var item in parsedJson)
{
    foreach (var smallitem in item)
    {
        foreach (var tag in smallitem)
        {
            if(tag.IsEnabled.toString()=="true"){
                Console.WriteLine("true");
            }                                 
        }
    }
}

这给了我正确的结果,除了它也迭代"计划作业"的事实。但主要问题是:


这是正确或最有效的方法吗?如果可能的话,建议一些更好的方法。

我知道的一个是使用类,但我可能事先不知道json结构。此外,json非常大,因此制作类可能会很麻烦!

解析复杂的 JSON:多个循环与类

鉴于您已经在执行JObject.Parse(jsonstring);来解析 JSON 字符串,您可以将SelectTokens()与 JSONPath 查询一起使用,以查找"JobProcessor"下的所有"JobName"对象:

// I want to check the "IsEnabled" property for all "JobName" for which come under "JobProcessors" 
foreach (var job in root.SelectTokens("..JobProcessors[?(@.JobName)]"))
{
    var isEnabled = (bool?)job["IsEnabled"];
    Debug.WriteLine(string.Format("Job {0}: IsEnabled={1}", job["JobName"], isEnabled));
}

笔记:

  • ..递归下降运算符:它递归下降JToken层次结构,返回每个项目,随后与查询字符串的其余部分进行匹配。

  • JobProcessors返回该名称的属性的值。

  • [?(@.JobName)]返回数组项(在本例中为 JobProcessors),这些数组项是具有 JobName 属性的对象。

  • (bool?)将"IsEnabled"的值强制转换为布尔值或 null(如果缺少)。

其输出为:

Job ArchivalJob: IsEnabled=True
Job AuditLogJob: IsEnabled=False

就像在你的代码片段中一样,我们使用两个foreach,对于大对象可能需要一些时间。因此,我们可以在单个foreach中做同样的事情,或者如果您有某些特定的节点要获取或搜索,则可以使用linq,为此,首先我们需要将json对象转换为c#对象。要将 Json 对象转换为 C#,您可以使用此站点"http://json2csharp.com/",然后我们可以将 Json 对象反序列化为 c#。

会是这样的

string jsonString = "your Json Object as string";
        var jsonObject = JsonConvert.DeserializeObject<RootObject>(jsonString);
        foreach (JobProcessor obj in jsonObject.JobProcessors)
        {
            string JobName = obj.JobName;
            bool value=obj.IsEnabled;
        }

我还在 c# 对象中转换了给定的 Json,如果 Json 对象相同,您可以直接使用这些类。

    public class Batching
    {
        public int BatchSize { get; set; }
        public int DegreeOfParallelism { get; set; }
    }
    public class Settings
    {
        public int ArchivalJobCollectionPageSize { get; set; }
    }
    public class JobProcessor
    {
        public string JobName { get; set; }
        public bool IsEnabled { get; set; }
        public Batching Batching { get; set; }
        public Settings Settings { get; set; }
    }
    public class Settings2
    {
        public string LeadTimeInSeconds { get; set; }
        public int MaxSrsJobCount { get; set; }
    }
    public class PrimaryAction
    {
        public string ConnectionString { get; set; }
        public Settings2 Settings { get; set; }
    }
    public class Settings3
    {
        public string LeadTimeInSeconds { get; set; }
        public int MaxSrsJobCount { get; set; }
    }
    public class ErrorAction
    {
        public string ConnectionString { get; set; }
        public string EntityPath { get; set; }
        public Settings3 Settings { get; set; }
    }
    public class ScheduledJob
    {
        public string JobName { get; set; }
        public PrimaryAction PrimaryAction { get; set; }
        public ErrorAction ErrorAction { get; set; }
    }
    public class RootObject
    {
        public List<JobProcessor> JobProcessors { get; set; }
        public List<ScheduledJob> ScheduledJobs { get; set; }
    }

希望这会有所帮助。谢谢