在json中JArray的任何地方提取元素

时间:2015-11-18 14:03:24

标签: c# arrays json json.net

让我们看看,json可以是动态的,并且可以在任何属性中包含多个嵌套数组。

示例:

{
    "items": [
        {
            "id": "0001",
            "name": "Cake",
            "batters": {
                "batter": [
                    {
                        "id": "1001",
                        "type": "Regular"
                    },
                    {
                        "id": "1002",
                        "type": "Chocolate"
                    },
                    {
                        "dry": [
                            {
                                "id": "1003",
                                "type": "Devil's Food"
                            }
                        ]
                    }
                ],
                "other": [
                    {
                        "id": "1004",
                        "type": "Home Food"
                    }
                ]
            },
            "topping": [
                {
                    "id": "5002",
                    "type": "Glazed"
                },
                {
                    "id": "5005",
                    "type": "Sugar"
                }
            ]
        },
        {
            "id": "0002",
            "name": "Sweets"
        }
    ]
}

一个简单的列表应该返回以下元素:

[
    {
        "id": "1001",
        "type": "Regular"
    },
    {
        "id": "1002",
        "type": "Chocolate"
    },
    {
        "id": "1003",
        "type": "Devil's Food"
    },
    {
        "id": "1004",
        "type": "Home Food"
    },
    {
        "id": "5002",
        "type": "Glazed"
    },
    {
        "id": "5005",
        "type": "Sugar"
    },
    {
        "id": "0002",
        "name": "Sweets"
    }
]

请注意: Json可以通过任何东西,没有属性可以用于提取,只需要知道所需的东西是JArray中的内容。

到目前为止我尝试过的只是一个开始:

public static bool ParseJsonArray(JToken token, List<string> extracts, string parentLocation = "")
        {
            if (token.HasValues)
            {
                foreach (JToken child in token.Children())
                {
                    if (token.Type == JTokenType.Array)
                    {
                        parentLocation += ((JProperty)token).Name;
                        extracts.Add(token.ToString());
                    }
                    ParseJsonArray(child, extracts, parentLocation);
                }
                return true;
            }
            else
            {
                return false;
            }
        }

token这里是解析的动态json。

1 个答案:

答案 0 :(得分:1)

看起来好像要递归查找本身不包含嵌套数组的所有JArray条目。我们称这些“叶子”数组条目。我这样说是因为你的结果中没有包含以下非叶条目:

    {
        "id": "0001",
        "name": "Cake"
    }

话虽如此,您可以使用以下扩展方法找到叶子数组条目:

public static class JsonExtensions
{
    public static IEnumerable<JToken> LeafArrayEntries(this JContainer container)
    {
        var nonLeafEntries = new HashSet<JToken>(container.DescendantsAndSelf()
            .OfType<JArray>()
            .SelectMany(a => a.Ancestors().Where(p => p.Type != JTokenType.Property)));
        return container.DescendantsAndSelf().Where(c => c.Parent is JArray && !nonLeafEntries.Contains(c));
    }
}

然后将返回的项目放在他们自己的数组中:

var leafItemArray = new JArray(rootJContainer.LeafArrayEntries());