这是我的问题
我在理解如何在JSON.NET中发现父级时仍然遇到问题
所以现在我有了这个JSON文档
{
"attributes": {"attr0":"value0"},
"children" : {
"ProductA" : {
"attributes": {"attr1":"value1", "attr2":"value2"},
"children" : {
"ProductC":{
"attributes": {"attr3":"value3", "attr4":"value4"},
"children" : {
"ProductD":{
"attributes": {"attr7":"value7", "attr8":"value8"},
"children" : {
"ProductE":{
"attributes": {"attr9":"value9", "attr10":"value10"},
"children" : {},
"referencedChildren" : {}
}
},
"referencedChildren" : {}
}
},
"referencedChildren" : {}
}
},
"referencedChildren" : {}
},
"ProductB" : {
"attributes": {"attr5":"value5", "attr6":"value6"},
"children" : {},
"referencedChildren" : {}
}
},
"referencedChildren" : {}
}
Run Code Online (Sandbox Code Playgroud)
基于此我写了这段代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.IO;
namespace JSonTest {
class Program {
static void Main(string[] args) {
string content = File.ReadAllText(@"c:\temp\foo.txt");
JObject token = JObject.Parse(content);
JToken p2 = token["children"]["ProductA"]["children"]["ProductC"]["children"]["ProductD"]["children"]["ProductE"];
JToken parent = p2;
do {
parent = GetParentModule(parent);
Console.WriteLine(((JProperty)parent).Name);
} while (parent != null);
}
private static JToken GetParentModule(JToken token) {
JToken retVal = token;
int i = 5;
while (i > 0) {
retVal = retVal.Parent;
if (retVal == null) {
break;
} else {
--i;
}
}
return retVal;
}
}
}
Run Code Online (Sandbox Code Playgroud)
当我运行此代码时,第一次调用GetParentModule返回"ParentD"...但第二次调用不返回"ParentC"
我的目标是,当我在ProductE上调用GetParentModule时,它返回ProductD,当我在ProductD上调用GetParentModule时,它返回ProductC,当我在ParentC上调用GetParentModule时,它返回ProductA.
在我之前的帖子中,我发现5次调用Parent,正确地返回了父级.但在后续调用中,我看到对Parent的"4"调用返回"ProductC".
您能否解释一下发生了什么以及如何成功地走上父层次结构?
我认为你很困惑,因为有两个因素在一起对你不利:
token["property"]通过抽象实际结构来简化JSON的向下遍历,以更好地适应您的心智模型.但是,向上导航没有这么方便,所以你会接触到所有额外的层.让我们以JSON的简化示例为例,详细了解一下正在发生的事情.假设我们有这个JSON:
{
"children": {
"ProductA": {
"children": {
"ProductC": {
"attribute": "some stuff"
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
在你的心理模型中你有这个:
但是Json.Net对象模型的工作原理如下:
JObject是JProperty对象的集合.JProperty是一个名称-值对,其中该名称是字符串和值可以是一个JObject,JValue或JArray.JObject是它的JProperties.JProperty是它的价值.所以JSON的实际内存表示是:
当你做这样的事情:
JObject productA = (JObject)top["children"]["ProductA"];
Run Code Online (Sandbox Code Playgroud)
这些额外的图层对你隐藏.它看起来就好像每个对象(或属性)直接嵌套在它上面的对象中.但不要被愚弄.在幕后,这个索引器语法实际上只是这个等效代码的快捷方式:
JObject productA = (JObject)top.Children<JProperty>()
.First(prop => prop.Name == "children")
.Value
.Children<JProperty>()
.First(prop => prop.Name == "ProductA")
.Value;
Run Code Online (Sandbox Code Playgroud)
希望到现在为止应该清楚发生了什么,我们可以回到你真正的问题,即如何上升链并获得理想的结果.例如,假设我们有对产品C的引用,并且我们想要获得产品A(或者更确切地说,我们引用了JObject,它是名为"ProductC"的JProperty的值,我们想要上升获取名称为"ProductA"的JProperty的值的链.我们怎么做?
好吧,再次,如果你看看实际的Json.Net结构,你可以看到它的模式.您已识别为"产品"的每个JObject都在JProperty中,其中"有趣"的名称不是"子".如果该产品具有"母产品",就会有一个祖先JProperty其名称为 "孩子".那个JProperty的父母是你想要的.
所以换句话说,你需要做的就是向上走,直到找到第一个名为"children"的JProperty,然后取出那个JProperty的父级,这应该是你正在寻找的JObject.
在代码中:
private static JToken GetParentModule(JToken token)
{
while (token != null &&
(token.Type != JTokenType.Property ||
((JProperty)token).Name != "children"))
{
token = token.Parent;
}
return (token != null ? token.Parent : null);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1398 次 |
| 最近记录: |