我在一个文本文件中存储了以下JSON文档
{
"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用C#编写了这段代码。NET库
string content = File.ReadAllText(@"c:tempfoo.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
没有名称,您得到的是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();
}