2016-07-12 5 views
0

ich einen Json vom Typ habe:Parsen komplexe JSON: mehr Schleifen vs. Klassen

{ 
"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 
    } 
    } 
} 
] 
} 

Ich mag das „IsEnabled“ Eigentum für alle „Jobnamen“, für die, die unter "überprüfen JobProcessoren "Kategorie. In C#, was ich bis jetzt verwendet habe, ist:

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

} 

Das ist mir, außer der Tatsache richtiges Ergebnis zu geben, dass es auch iteriert für „ScheduledJobs“. Aber das Hauptproblem ist:


Ist dies der richtige oder effizienteste Weg, dies zu tun? Wenn möglich, schlagen Sie eine bessere Methode vor.

Eine, die ich kenne, verwendet Klassen, aber ich kann nicht die JSON-Struktur im Voraus kennen. Auch der JSON ist sehr groß, so dass der Unterricht schwerfällig sein kann !!

+0

Warum Sie in 'dynamic' parsen? Erstellen Sie besser ein stark typisiertes Objekt, um Ihre Struktur zu repräsentieren – haim770

+0

Schalten Sie die foreach mit einer for-Schleife. Die for-Schleife ist immer schneller als eine für jede Schleife –

+0

@ haim770 Ich kann die Struktur der Klasse vorher nicht kennen. – Arushi

Antwort

1

Da Sie bereits JObject.Parse(jsonstring); tun Ihre JSON-Zeichenfolge zu analysieren, Sie SelectTokens() mit einem JSONPath query können alle „Jobname“ Objekte unter „JobProcessors“ zu finden:

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

Anmerkungen:

  • .. ist der rekursiven Abstieg Operator: es rekursiv den JToken hiera absteigt rchy jedes Element zurückgeben, anschließend mit den übrigen Teilen der Abfragezeichenfolge verglichen werden.

  • JobProcessors gibt Werte von Eigenschaften dieses Namens zurück.

  • [?(@.JobName)] liefert Array-Elemente (von JobProcessors in diesem Fall), die Objekte mit einer JobName-Eigenschaft sind.

  • (bool?) wandelt den Wert von "IsEnabled" in einen Booleschen Wert oder Null, wenn dieser fehlt.

Und die Ausgabe dieser ist:

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

Danke speziell dafür '[? (@. JobName)]'. – Arushi

1

Wie in Ihrem Code-Snippet verwenden wir zwei foreach es kann Zeit für großes Objekt dauern. So können wir das gleiche in einer einzelnen foreach tun oder wenn Sie einen bestimmten Knoten zum Abrufen oder Suchen haben, können wir linq verwenden, und zuerst müssen wir unser json-Objekt in C# -Objekt konvertieren. Zum Konvertieren von Json-Objekten in C# können Sie diese Site "http://json2csharp.com/" verwenden, dann können wir das Json-Objekt in C# deserialisieren.

Es wird so etwas wie diese

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

Und ich konvertierte auch Json in C# Objekt gegeben, wenn das JSON-Objekt gleich ist direkt diese Klassen verwenden kann.

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

Hoffe, das wird helfen. Danke

+0

Vielen Dank für diesen Ansatz, aber ich wollte keine Klassen verwenden! – Arushi