2016-02-01 3 views
0

Мне сложно получить родительский ключ/свойство/атрибут моих объектов JSON с помощью JSON.net. То есть, я хочу имя outermost, как строку, не зная заранее/визуально, что это такое. В настоящее время я итерация набора KeyValuePair элементов и пытаюсь, для каждого из них, выйти из родителей от чего-то, что выглядит какРодительский ключ JSON.net

{"parentKey": 
{ 
    "Name": "Name", 
    "Id": "123", 
    "Other": null, 
    "nestedArr": 
    [ 
    "idx0", 
    "idx1", 
    "idx2" 
    ] 
} 
} 

Я попытался как keyValue.Value.Ancestors() и keyValue.Value.Parent. С первым я получаю то, что выглядит как определение функции ... Я на самом деле не уверен, что это такое: Newtonsoft.Json.Linq.JToken+<GetAncestors>d_ _ 42. Полностью одурманивается этим, потому что на основе примеров использования, которые я придумал здесь, я использую его по стандарту.

С последним я выхожу из всего объекта, а также то, что кажется всем предшествующим KeyValuePair, а не просто строкой «parentKey», что я и хочу. Документы JSON.net не являются лучшими, насколько явные примеры использования и что ожидать (или, может быть, это просто новоиспользуется для C#, я не могу их понять), но в любом случае я добрый неясно, почему это происходит и как выполнить то, что я хочу. Это то, что я пытаюсь:

foreach (var keyValue in jObjList[0]) //jObjList is a List<JObject> defined above 
{ 
    Console.WriteLine(keyValue.Value.Ancestors()); 
    Console.WriteLine(keyValue.Value.Parent); 
    if (keyValue.Value.GetType() == typeof(JObject))//same block goes for if it's typeof(JArray) 
    { 
     Console.WriteLine(keyValue.Key); 
    } 
} 

Edit: в формате JSON дано, и в пределах цикла, определенные выше, например, для того, чтобы получить мои родительские ключи (это только то, что я называю их), мой код просто говорит: if (keyValue.Value.GetType() == typeof(JObject), напишите keyValue.Key на консоль, и то же самое происходит, если getType() - это JArray. В любом случае keyValue.Key является родительским ключом, если это имеет смысл. Я хочу сказать, что это свойство указывает на другой массив или объект. Моя проблема в том, что, когда я делаю этот цикл рекурсивно, когда я перехожу к вложенному массиву или объекту, мой код не может этого понять, хотя в настоящее время существует новый «родительский ключ», например, с nestedArr, для Например, родительский ключ nestedArr по-прежнему является «parentKey».

код сокращен, но это идея.

Все разъяснения и исправления приветствуются и оцениваются. Благодарю.

ответ

3

Вы видите Newtonsoft.Json.Linq.JToken+<GetAncestors>d_ _ 42 для Console.WriteLine(keyValue.Value.Ancestors()), потому что Ancestors является IEnumerable<T> чья оценка lazy, а не явной коллекции. То, что вы видите, это вывод ToString() вывода, который еще не оценен.

Если то, что вы хотите сделать, это подняться родительский список данного JToken и найти самый низкий родитель, который имеет "parentKey" свойство, а затем получить значение этого parentKey, то это, как вы могли бы сделать это:

JToken token = keyValue.Value; // Here I'm declaring JToken explicitly for clarity. Normally I would use var token = ... 

    var parentKey = token.AncestorsAndSelf()  // Climb up the json container parent/child hierachy 
     .Select(p => p.SelectToken("parentKey")) // Get the "parentKey" property in the current parent (if present) 
     .FirstOrDefault(k => k != null);   // Return the first one found. 

    Console.WriteLine(parentKey); 

Update

Чтобы получить имя свойства JSON высокий в контейнере иерархии JSON, вы могли бы сделать:

var name = token.AncestorsAndSelf() // Walk up the list of ancestors 
     .OfType<JProperty>()   // For each that is a property 
     .Select(p => p.Name)   // Select the name 
     .LastOrDefault();    // And return the last (topmost). 

Update 2

Если вы ищете первый имя свойства , которое появляется в файле формата JSON, вы можете сделать следующее, используя JContainer.DescendantsAndSelf():

var json = @"[{""parentKey"": 
    { 
     ""Name"": ""Name"", 
     ""Id"": ""123"", 
     ""Other"": null, 
     ""nestedArr"": 
     [ 
     ""idx0"", 
     ""idx1"", 
     ""idx2"" 
     ] 
    } 
    }]"; 

    var root = (JContainer)JToken.Parse(json); 
    var name = root.DescendantsAndSelf() // Loop through tokens in or under the root container, in document order. 
     .OfType<JProperty>()    // For those which are properties 
     .Select(p => p.Name)    // Select the name 
     .FirstOrDefault();    // And take the first. 

    Debug.WriteLine(name); // Prints "parentKey" 

(JContainer представляет узел JSON, который может содержать дочерние узлы, такие как объект или массив.)

+0

Я действительно не понимаю, как la mbdas работают в вашем примере. не могли бы вы прокомментировать, что там происходит? Кроме того, мне нужен способ доступа к «parentKey», анонимно, если хотите. Я не знаю, что такое «parentKey», поэтому я не могу передать его в качестве параметра. Мне просто нужно динамически знать, что такое внешнее свойство keyValuePair. Я отредактирую свой Q для ясности. – spb

+0

@spb - Если вы можете отредактировать свой вопрос, включив в него полный пример своего JSON и то, что вам нужно распечатать на консоли, я, вероятно, объясню более четко. – dbc

+0

благодарит за комментирование кода. :) Очень полезно. надеюсь, мои изменения пролить свет на то, что я пытаюсь выполнить/что я работаю с – spb

Смежные вопросы