C# 从JToken获得家长的困惑
我将以下JSON文档存储在一个文本文件中C# 从JToken获得家长的困惑,c#,json,json.net,C#,Json,Json.net,我将以下JSON文档存储在一个文本文件中 { "attributes": {"attr0":"value0"}, "children" : { "ProductA" : { "attributes": {"attr1":"value1", "attr2":"value2"}, "children" : { "ProductC":{ "attri
{
"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#中编写了这段代码
string content = File.ReadAllText(@"c:\temp\foo.txt");
JToken token = JToken.Parse(content);
JToken p2 = token["children"]["ProductA"]["children"]["ProductC"];
这是可行的,我得到了p2
的节点
但是,如果我想从p2
节点获取ParentA
的节点。我不得不说
JToken p1 = p2.Parent.Parent.Parent.Parent.Parent;
Console.WriteLine(((JProperty)p1).Name);
上面的代码打印出“ProductA”
。但令人困惑的是,为什么我要给父母打5次电话
当我查看文档时,我可以看到“children”
是“ProductC”
的父级,然后“ProductA”
是子级的父级。因此,对Parent
的两次调用应该会让我ParentA
为什么我需要5个调用?您正在遍历的层次结构是Json.net如何构造对象,它并不代表Json字符串本身 相对于
ProductA
对象(好吧,向上一个),下面是如何进入ProductC
:
JProperty: "ProductA"
-> JObject (ProductA object)
-> JProperty: "children"
-> JObject (children object)
-> JProperty: "ProductC"
-> JObject (ProductC object) *you are here
因此,如果您这样看,您应该看到您实际上是在访问JProperty
“ProductA”(5个父对象),而不是对象本身。您可能已经注意到,JObject
s没有名称,您得到的是JProperty
的名称
我无法告诉您如何访问它,因为json字符串中描述了它,它似乎不是一个选项。但是您当然可以编写一些助手方法来为您获取它们
下面是一个获取父对象的实现。我不知道我们还会遇到哪些我们想跳过的JToken,但这是一个开始。只需传入您要获取其父项的令牌。传入一个可选的父编号,以指示所需的父编号
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 GetParent(JToken令牌,int parent=0)
{
if(标记==null)
返回null;
如果(父级<0)
抛出新ArgumentOutOfRangeException(“必须为正”);
var skipTokens=new[]
{
类型(JProperty),
};
返回标记。祖先()
.Where(a=>skipTokens.All(t=>!t.IsInstanceOfType(a)))
.Skip(父级)
.FirstOrDefault();
}
。我一时不知道答案,但那将是我下一步的诊断步骤。