2013-12-12 11 views
6

Ho il seguente documento JSON memorizzato in un file di testoJSON.NET - Confusione a ottenere Parent da 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" : {} 
} 

Ho scritto questo codice in C# utilizzando NewtonSoft JSon.NET Biblioteca

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

Funziona e ottengo il nodo per p2.

Tuttavia ... se desidero il nodo per ParentA dal nodo p2. Devo dire

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

Il codice di cui sopra stampe "Producta" ... Ma la parte di confusione è che il motivo per cui devo chiamare controllanti "5" volte.

Quando guardo il mio documento, posso vedere che "children" è il genitore di "ProductC" e quindi "ProductA" è il genitore dei bambini. Quindi 2 chiamate a Parent dovrebbero aver ottenuto il mio ParentA.

Perché ho bisogno di 5 chiamate?

+1

Ti suggerisco di guardare quello che hai a ogni livello di "genitore". Non conosco la risposta, ma quello sarebbe il mio prossimo passo diagnostico. –

risposta

6

La gerarchia che stai attraversando è come Json.net struttura gli oggetti, non è rappresentativo della stringa json stessa.

relativa all'oggetto ProductA (beh, uno in alto), questo è come si arriva al ProductC:

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

Quindi, se si guarda in questo modo, si dovrebbe vedere che in realtà si sta accedendo al JProperty "ProdottoA" (5 genitori attivi), non l'oggetto stesso. Come potresti aver notato, JObject s non hanno un nome, stai ricevendo il nome dello JProperty.

Non posso dirvi in ​​che modo è possibile accedervi esattamente come descritto nella stringa JSON, non sembra essere un'opzione. Ma potresti naturalmente scrivere alcuni metodi di supporto per ottenerli per te.

Ecco un'implementazione per ottenere l'oggetto padre. Non so quali altri JTokens incontreremmo che vorremmo saltare, ma questo è un inizio. Basta passare il token che si desidera ottenere il genitore di. Passa un numero genitore facoltativo per indicare quale genitore desideri.

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(); 
} 
Problemi correlati