2017-02-10 3 views
1

Ich erhalte eine JSON-Datei, die eine Liste von Dateien mit jeweils einer Zahl enthält, die die Gesamtzahl der darin enthaltenen Zeilen darstellt. Die Dateinamen können sich im Laufe der Zeit ändern. Bietet JSON.NET einen Mechanismus zur Handhabung dieses Szenarios?Analysieren von dynamischen JSON

In der folgenden Beispiel-JSON interessiert mich speziell Artikel unter noOfProductsByFile. Die Liste der Dateien ist variabel und ich müsste sie durch irgendeine Art von dynamischem Objekt konsumieren.

{ 
    "noOfProductsByFileType" : { 
    "rdi_product_stuff" : 41228, 
    "rdi_product_junk" : 62519, 
    "rdi_product_otherStuff" : 165023, 
    "rdi_product_bobsJunk" : 1289 
    }, 
    "startTime" : "20160907050000", 
    "endTime" : "20160907052713", 
    "timeTaken" : "27 minutes and 13 seconds", 
    "noOfProductsBySecurityType" : { 
    "AGENCIES" : 41228, 
    "ASTBK" : 50991, 
    "TSYCURV" : 78 
    }, 
    "noOfProductsByFile" : { 
    "rdi_product_stuff_1_of_1.json" : 41228, 
    "rdi_product_junk_1_of_2.json" : 60219, 
    "rdi_product_junk_2_of_2.json" : 2300, 
    "rdi_product_myStuff_1_of_2.json" : 147690, 
    "rdi_product_myStuff_2_of_2.json" : 17333, 
    "rdi_product_test_1_of_1.json" : 1289 
    }, 
    "noOfProducts" : 1925914 
} 
+0

ja es tut, wie Sie den JSON-Text analysieren und nicht die Datei – NicoRiff

Antwort

6

Es gibt ein paar Optionen zu verwenden. Hier ist man den ExpandObject mit

dynamic dynData = JsonConvert.DeserializeObject<ExpandoObject>(jsonString, new ExpandoObjectConverter()); 

Sie können dann die Felder verweisen auf wie ein normales Objekt:

dynData.noOfProductsByFileType.rdi_product_stuff 

Wenn Sie Felder behandeln, die nicht vorhanden sein kann oder nicht, ExpandoObjects gegossen werden kann zu einer IDictionary und auf Felder beziehen sich wie folgt:

((IDictionary<string,object>)dynData)["noOfProductsByFileType"] 

Assign auf eine Art und IDictionary iterieren Eigenschaften oder Test, ob eine Eigenschaft

01 vorhanden ist
var dictData = (IDictionary<string,object>)dynData; 
var noOfProductsByFileTypeDict = (IDictionary<string,object>)dynData.noOfProductsByFileType; // objects within objects 

Test für Immobilien

dictData.containsKey("testprop"); // test for a property - testprop 

oder Iterate

foreach (KeyValuePair<string, int> pair in noOfProductsByFileTypeDict) ... //iterate 
+0

Schöne Antwort! OP wird wahrscheinlich lieber die Namen dieser Dateien iterieren als hart codieren. Es ist eine dynamische Liste. Aber ich sehe, dass man mit 'ExpandoObject' sicher' foreach' über 'dynData.noOfProductsByFile' und dann die' .Key' und '.Value' Eigenschaften ablesen kann. Vielleicht möchten Sie Ihre Antwort ändern. –

+0

FWIW: Sie müssen nicht wirklich _geed_ in ein Wörterbuch umwandeln. Sie können einfach 'foreach (var-Eigenschaft in dynData.noOfProductsByFile)' und dann 'string file = property.Key;' und 'long noOfProducts = property.Value;'. –

2

Ja. Es gibt eine Reihe von Möglichkeiten, damit umzugehen. Eine einfache Möglichkeit ist die Verwendung eines JObject.

var jsonString = "..."; 
var jObject = JObject.Parse(jsonString); 
foreach (JProperty e in jObject["noOfProductsByFile"]) 
{ 
    var file = e.Name; 
    var noOfProducts = e.Value; 
    Debug.WriteLine(file); 
    Debug.WriteLine(noOfProducts); 
} 
+0

Sie können auch JObject.Parse (jsonstring) anstelle von JsonConvert –

+0

Guter Fang verwenden. Aktualisiert. –