2016-11-17 20 views
4

JSONストリームをサーバーから取得しています.JSON.netを使用してノード "ID"の特定の値を検索する必要がありますデータを解析します。 そして、私はほとんどそれを動作させることができますが、戻ってくる結果が深く入れ子になっているからです。これは、フォルダ構造を元に戻しているためです。 JSONをはるかに単純なバージョンに煮詰めました。私はそれがオブジェクトを解析するだろうとデバッグビューで見ることができますが、させませんC#でJSON.netオブジェクトのネストされた値を検索する

var objects = JObject.Parse(results); 
var subobjects = objects["data"]["childFolders"][0]["childFolders"][1]; 

:私はほとんど行くことによってそこに着くことができ

{ 
    "data": { 
     "id": 0, 
     "name": "", 
     "childFolders": [{ 
      "id": 19002, 
      "name": "Locker", 
      "childFolders": [{ 
       "id": 19003, 
       "name": "Folder1", 
       "childFolders": [], 
       "childComponents": [{ 
        "id": 19005, 
        "name": "route1", 
        "state": "STOPPED", 
        "type": "ROUTE" 
       }] 
      }, { 
       "id": 19004, 
       "name": "Folder2", 
       "childFolders": [], 
       "childComponents": [{ 
        "id": 19008, 
        "name": "comm1", 
        "state": "STOPPED", 
        "type": "COMMUNICATION_POINT" 
       }, { 
        "id": 19006, 
        "name": "route2", 
        "state": "STOPPED", 
        "type": "ROUTE" 
       }, { 
        "id": 19007, 
        "name": "route3", 
        "state": "STOPPED", 
        "type": "ROUTE" 
       }] 
      }], 
      "childComponents": [] 
     }], 
     "childComponents": [] 
    }, 
    "error": null 
} 

:私はこれを取得しています私は以内に検索します。

私の究極の目標は、そのルートのIDなので、「route3」を検索して19007に戻ることができるようにすることです。私はいくつかの結果を見つけましたが、それらのすべてはオブジェクトがどれくらい入れ子になっているかを知っていると仮定しています。私が探しているオブジェクトは、深さが2深いか、深さが20深くなる可能性があります。

答えて

4

の詳細ドキュメントを見つけることができます私の究極の目標は、「route3」を検索して取得することができることですバック19007

あなたはLINQ子孫を使用することができますJOBJECTの方法は、それを行うには:

var dirs = JObject.Parse(json) 
      .Descendants() 
      .Where(x=>x is JObject) 
      .Where(x=>x["id"]!=null && x["name"]!=null) 
      .Select(x =>new { ID= (int)x["id"], Name = (string)x["name"] }) 
      .ToList(); 

var id = dirs.Find(x => x.Name == "route3").ID; 
+0

私たちが本当に興味を持っているのはIDなので、簡略化することができます: 'var id = JObject.Parse(json).Descendants()。OfType ().Where(x =>(string)x [" name FirstOrDefault(); ' –

+0

これはきれいに機能しました - これを書いてくれてありがとうございます(" id ")!==" route3 "&& x [" id "]!= null) 。 – EtanSivad

3

だけで再帰関数を記述します。

private Thing FindThing(Thing thing, string name) 
{ 
    if (thing.name == name) 
     return thing; 
    foreach (var subThing in thing.childFolders.Concat(thing.childComponents)) 
    { 
     var foundSub = FindThing(subThing, name); 
     if (foundSub != null) 
      return foundSub; 
    } 
    return null; 
} 

class RootObject 
{ 
    public Thing data { get; set; } 
} 

class Thing 
{ 
    public int id { get; set; } 
    public string name { get; set; } 
    public List<Thing> childFolders { get; set; } = new List<Thing>(); 
    public List<Thing> childComponents { get; set; } = new List<Thing>(); 
} 

そして、それを使用して:

var obj = JsonConvert.DeserializeObject<RootObject>(jsonString); 
var result = FindThing(obj.data, "route3"); 
+0

は、「それは何ですか? – Benj

3

あなたはあなたの目的のノードを検索するJPathを提供するために、SelectTokenまたはSelectTokens機能を使用することができます。ここではあなたの名前に基づいて経路を提供する例です。

JObject.Parse(jsonData)["data"].SelectToken("$..childComponents[?(@.name=='route3')]") 

あなたはJPath here

関連する問題