在C#中搜索JSON.net对象内的嵌套值

时间:2016-11-17 23:00:37

标签: c# json json.net

我有一个从服务器返回的JSON流,我需要使用JSON.net搜索节点“ID”的特定值来解析数据。 我几乎可以使它工作,但不完全是因为返回的结果彼此深深地嵌套 - 这是因为我正在获得一个文件夹结构。我把JSON简化为更简单的版本。我明白了:

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

我几乎可以去那里:

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

我可以在调试视图中看到它将解析对象,但不会让我在其中搜索。

我的最终目标是能够搜索“route3”并返回19007,因为那是该路线的ID。我发现了一些结果,但是所有结果都假设你知道对象的嵌套距离。我正在搜索的对象可能是2深或20深。

3 个答案:

答案 0 :(得分:8)

  

我的最终目标是能够搜索" route3"并回到19007

您可以使用JObject的 linq Descendants 方法来执行此操作:

set HEAP=-Xms512m -Xmx512m

答案 1 :(得分:4)

您可以使用SelectTokenSelectTokens函数提供JPath来搜索您想要的节点。这是一个基于名称为您提供路线的示例:

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

您可以在JPath here

上找到更多文档

答案 2 :(得分: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");