2013-12-12 2 views
6

У меня есть следующие JSON документ, хранящийся в текстовом файлеJSON.NET - Путаница в получении Родитель от JToken

{ 
    "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" : {} 
} 

Я написал этот код в C# с использованием 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.

Однако ... если я хочу узел ParentA из узла p2. Я должен сказать, что

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

код, приведенный выше гравюр «ProductA» ... Но запутанная часть является то, что почему я должен назвать родительским «5» раз.

Когда я смотрю на свой документ, я вижу, что «дети» являются родителями «ProductC», а затем «ProductA» является родительским элементом для детей. Поэтому 2 вызова родителя должны были получить ParentA.

Зачем мне 5 звонков?

+1

Предлагаю вам посмотреть, что у вас есть на каждом уровне «родителя». Я не знаю ответа, но это будет мой следующий диагностический шаг. –

ответ

6

Иерархия, с которой вы проходите, - это то, как 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, это не похоже на вариант. Но вы могли бы, конечно, написать некоторые вспомогательные методы, чтобы получить их для вас.

Вот одна реализация, чтобы получить родительский объект. Я не знаю, что другие JTokens мы встретим, что мы хотим пропустить, но это начало. Просто пройдите в токен, который вы хотите получить от родителя. Передайте необязательный родительский номер, чтобы указать, какой родитель вы хотите.

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(); 
} 
Смежные вопросы