确定JToken是否为叶子

时间:2015-12-24 20:21:17

标签: c# json json.net

我试图动态地找到结构事先不知道的JSON对象的叶节点的名称。首先,我将字符串解析为JTokens列表,如下所示:

        string req = @"{'creationRequestId':'A',
                        'value':{
                            'amount':1.0,
                            'currencyCode':'USD'
                        }
                        }";
        var tokens = JToken.Parse(req);

然后我想确定哪些是叶子。在上面的示例中,'creationRequestId':'A''amount':1.0'currencyCode':'USD'是叶子,名称是creationRequestIdamountcurrencyCode

尝试有效,但有点难看

以下示例以递归方式遍历JSON树并打印叶名称:

    public static void PrintLeafNames(IEnumerable<JToken> tokens)
    {
        foreach (var token in tokens)
        {
            bool isLeaf = token.Children().Count() == 1 && !token.Children().First().Children().Any();
            if (token.Type == JTokenType.Property && isLeaf)
            {
                Console.WriteLine(((JProperty)token).Name);
            }

            if (token.Children().Any())
                PrintLeafNames(token.Children<JToken>());
        }
    }

这有效,打印:

creationRequestId
amount
currencyCode

然而,我想知道是否有一个不那么丑陋的表达来判断一个JToken是否是叶子:

bool isLeaf = token.Children().Count() == 1 && !token.Children().First().Children().Any();

Incidentally, this is a one-liner in XML.

1 个答案:

答案 0 :(得分:4)

看起来您已将一个叶子定义为其值不具有任何子值的任何JProperty。您可以使用HasValues上的JToken属性来帮助您做出此决定:

public static void PrintLeafNames(IEnumerable<JToken> tokens)
{
    foreach (var token in tokens)
    {
        if (token.Type == JTokenType.Property)
        {
            JProperty prop = (JProperty)token;
            if (!prop.Value.HasValues)
                Console.WriteLine(prop.Name);
        }
        if (token.HasValues)
            PrintLeafNames(token.Children());
    }
}

小提琴:https://dotnetfiddle.net/e216YS