从JToken获取Parent的困惑 [英] Confusion in getting Parent from JToken

查看:209
本文介绍了从JToken获取Parent的困惑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将以下JSON文档存储在文本文件中

I have the following JSON document stored in a text file

{
    "attributes": {"attr0":"value0"},
    "children" : {
        "ProductA" : {
            "attributes": {"attr1":"value1", "attr2":"value2"}, 
            "children" : {
                "ProductC":{
                    "attributes": {"attr3":"value3", "attr4":"value4"}, 
                    "children" : {}, 
                    "referencedChildren" : {}
                }
            }, 
            "referencedChildren" : {}
        }, 
        "ProductB" : {
            "attributes": {"attr5":"value5", "attr6":"value6"}, 
            "children" : {}, 
            "referencedChildren" : {}
        }
    },
    "referencedChildren" : {}
}

我已经使用NewtonSoft JSon.NET库用C#编写了这段代码

I have written this code in C# using NewtonSoft JSon.NET Library

string content = File.ReadAllText(@"c:\temp\foo.txt");
JToken token = JToken.Parse(content);
JToken p2 = token["children"]["ProductA"]["children"]["ProductC"];

这有效,我得到了p2的节点.

This works and I get the node for p2.

但是,如果我要从p2节点获取ParentA的节点.我不得不说

However if I want the node for ParentA from the p2 node. I have to say

JToken p1 = p2.Parent.Parent.Parent.Parent.Parent;
Console.WriteLine(((JProperty)p1).Name);

上面的代码打印"ProductA".但是令人困惑的是,为什么我必须打电话给父母5次.

The code above prints "ProductA". But the the confusing part is that why do I have to call parent 5 times.

当我查看文档时,可以看到"children""ProductC"的父级,然后"ProductA"是子级的父级.因此,对Parent的两次呼叫应该让我ParentA.

When I look at my document, I can see that "children" is the parent of "ProductC" and then "ProductA" is the parent of children. Therefore 2 calls to Parent should have got me ParentA.

为什么我需要打5个电话?

Why do I need 5 calls?

推荐答案

您正在遍历的层次结构是Json.net构造对象的方式,它不代表json字符串本身.

The hierarchy you're traversing is how Json.net structures the objects, it is not representative of the json string itself.

相对于ProductA对象(很好,一个向上),这是您进入ProductC的方式:

Relative to the ProductA object (well, one up), this is how you get down to ProductC:

JProperty: "ProductA"
 -> JObject (ProductA object)
     -> JProperty: "children"
         -> JObject (children object)
             -> JProperty: "ProductC"
                 -> JObject (ProductC object)  *you are here

因此,如果以这种方式看待它,应该看到实际上是在访问JProperty"ProductA"(最多5个父级),而不是对象本身.您可能已经注意到,JObject没有名称,您正在获取JProperty的名称.

So if you look at it this way, you should see that you are actually accessing the JProperty "ProductA" (5 parents up), not the object itself. As you might have noticed, JObjects do not have a name, you're getting the name of the JProperty.

我无法告诉您您可以多么准确地访问它,如json字符串中所述,它似乎不是一个选项.但是您当然可以编写一些辅助方法来帮助您.

I can't tell you how exactly you can access it as it is described in the json string, it doesn't appear to be an option. But you could of course write some helper methods to get them for you.

这是获取父对象的一种实现.我不知道我们还会跳过哪些其他JToken,但这只是一个开始.只需传递您想要获得其父代的令牌即可.传递一个可选的父母编号以指示您想要的父母.

Here's one implementation to get the parent object. I don't know what other JTokens we'd encounter that we'd want to skip, but this is a start. Just pass in the token you want to get the parent of. Pass in an optional parent number to indicate which parent you want.

JToken GetParent(JToken token, int parent = 0)
{
    if (token == null)
        return null;
    if (parent < 0)
        throw new ArgumentOutOfRangeException("Must be positive");

    var skipTokens = new[]
    {
        typeof(JProperty),
    };
    return token.Ancestors()
        .Where(a => skipTokens.All(t => !t.IsInstanceOfType(a)))
        .Skip(parent)
        .FirstOrDefault();
}

这篇关于从JToken获取Parent的困惑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆