在json中的任意位置提取JArray元素

本文关键字:提取 JArray 元素 位置 任意 json | 更新日期: 2023-09-27 18:22:20

让我们看看,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。

在json中的任意位置提取JArray元素

似乎您想要递归地查找所有本身不包含嵌套数组的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());