Как разобрать объект JSON на C #, если я заранее не знаю ключ?
У меня есть данные JSON, которые выглядят так:
{ "910719": { "id": 910719, "type": "asdf", "ref_id": 7568 }, "910721": { "id": 910721, "type": "asdf", "ref_id": 7568 }, "910723": { "id": 910723, "type": "asdf", "ref_id": 7568 } }
Как я могу разобрать это с помощью JSON.net? Я могу сначала сделать это:
JObject jFoo = JObject.Parse(data);
Мне нужно иметь возможность перебирать каждый объект в этом списке. Я хотел бы иметь возможность сделать что-то вроде этого:
- JSON.NET Parser * кажется * будет двойной сериализацией моих объектов
- Разбор JSON с использованием Json.net
- Уничтожить вложенные JSON в объекты C #
- Как я могу зашифровать выбранные свойства при сериализации моих объектов?
- Использование преобразователей Json.NET для десериализации свойств
foreach (string ref_id in (string)jFoo["ref_id"]) {...}
или
foreach (JToken t in jFoo.Descendants()) { Console.WriteLine((string)t["ref_id"]); }
но, конечно, это не сработает. Все примеры отлично работают, если вы знаете ключ при написании кода. Он ломается, когда вы заранее не знаете ключ.
- Уничтожить stream массива json по одному элементу за раз
- Как обрабатывать как отдельный элемент, так и массив для одного и того же свойства с помощью JSON.net
- JSON.NET - как десериализовать сборку интерфейсных экземпляров?
- Могу ли я сериализовать вложенные свойства в мой class за одну операцию с помощью Json.net?
- Как программно выбирать конструктор во время десериализации?
- JSON.Net Xml Сериализация неправильно понимает массивы
- Как получить json.net для сериализации членов classа, полученных из List ?
- Каков правильный способ использования JSON.NET для анализа streamа объектов JSON?
Это выполнимо; это работает, но это не изящно. Я уверен, что есть лучший способ.
var o = JObject.Parse(yourJsonString); foreach (JToken child in o.Children()) { foreach (JToken grandChild in child) { foreach (JToken grandGrandChild in grandChild) { var property = grandGrandChild as JProperty; if (property != null) { Console.WriteLine(property.Name + ":" + property.Value); } } } }
Печать:
ID: 910719 Тип: ASDF ref_id: 7568 ID: 910721 Тип: ASDF ref_id: 7568 ID: 910723 Тип: ASDF ref_id: 7568
Вы можете перебирать потомков простым запросом LINQ следующим образом:
JObject jFoo = JObject.Parse(json); foreach (JObject obj in jFoo.Properties().Select(p => p.Value)) { Console.WriteLine("id: " + obj["id"]); Console.WriteLine("ref_id: " + obj["ref_id"]); }
Аналогичным образом, если вы хотите получить только значения ref_id
, вы можете получить следующие значения:
foreach (string refId in jFoo.Properties().Select(p => p.Value["ref_id"])) { Console.WriteLine(refId); }
Я использую Json.NET, и я быстро написал, где вы можете распечатать все ключи и соответствующие значения с помощью рекурсивного метода.
var o = JObject.Parse(YourJsonString); getAllProperties(o); //call our recursive method
Затем вы можете использовать этот рекурсивный метод для получения всех свойств и их значений
void getAllProperties(JToken children) { foreach (JToken child in children.Children()) { var property = child as JProperty; if (property != null) { Console.WriteLine(property.Name + " " + property.Value);//print all of the values } getAllProperties(child); } }
Вы рассматривали использование JavascriptSerializer?
вы можете попробовать сделать что-то вроде этого:
JavaScriptSerializer serializer = new JavaScriptSerializer(); var foo = serializer.Deserialize>>(data); foreach(var item in foo) { Console.Writeln(item.Value["ref_id"]); }
http://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.aspx
Решение Konstantin будет работать, но если вы хотите, чтобы список Id делал то же самое, а вместо Console.Writeln () использовали следующие
List list = new List (); JavaScriptSerializer serializer = new JavaScriptSerializer(); var foo = serializer.Deserialize>>(data); foreach(var item in foo) { list.Add(item.Value["ref_id"]); }
Я нашел ответ TrueWill, но я хотел избежать foreach и попытаться получить простой цикл для работы ради скорости. Мои результаты были, безусловно, тем, что в лучшем случае можно было бы назвать уродливым. Здесь они на случай, если они полезны для всех. (Я ушел в WriteLine, чтобы быть в состоянии видеть вещи немного легче.)
Обратите внимание, что это не сработает для некоторых JSON и не является совершенно общим. Некоторые нулевые проверки могут быть выполнены лучше и т. Д.
// NOW, DOING IT ALL AS A FOR LOOP... // a, b, c, d - for iterator counters. // j1, j2, j3, j4 - the JTokens to iterator over - each is a child of the previous // p, q, r, s - The properties from j1/2/3/4. JObject o = JObject.Parse(json); JToken j1 = o.First; for (int a = 0; a < o.Children().Count(); a++) { // Outermost loop gives us result, error, id. if (j1 == null) continue; if (a > 0) { j1 = j1.Next; if (j1 == null) continue; } var p = j1 as JProperty; Console.WriteLine("FOR 0 = " + a.ToString() + " --- " + p.Name); // DO STUFF HERE. // FIRST INNER LOOP // Set up a JToken or continue JToken j2 = j1.Children().First() as JToken; if (j1.Children().Count() > 0) { j2 = j1.Children().First() as JToken; } else { continue; } Console.WriteLine("*** STARTING FIRST INNER..."); for (int b = 0; b < j1.Children().Count(); b++) { // returns nothing as second loop above. if (j2 == null) { Console.WriteLine("*** j2 null 1..."); continue; } if (b > 0) { j2 = j2.Next; if (j2 == null) { Console.WriteLine("*** j2 null 2..."); continue; } } var q = j2 as JProperty; // These null checks need to be != or ==, depending on what's needed. if (q != null) { Console.WriteLine("FOR 1 = " + a.ToString() + "," + b.ToString() + " --- " + q.Name); // DO STUFF HERE. // ... } // q !null check // SECOND INNER LOOP // Set up a JToken or continue JToken j3; if (j2.Children().Count() > 0) { j3 = j2.Children().First() as JToken; } else { continue; } Console.WriteLine("****** STARTING SECOND INNER..."); for (int c = 0; c < j2.Children().Count(); c++) { if (j3 == null) continue; if (c > 0) { j3 = j3.Next; if (j3 == null) continue; } var r = j3 as JProperty; if (r == null) { continue; } // r null check Console.WriteLine("FOR 2 = " + a.ToString() + "," + b.ToString() + "," + c.ToString() + " --- " + r.Name); // DO STUFF HERE. // THIRD INNER LOOP // Set up a JToken or continue JToken j4; if (j3.Children().Count() > 0) { j4 = j3.Children().First() as JToken; } else { continue; } Console.WriteLine("********* STARTING THIRD INNER..."); for (int d = 0; d < j3.Children().Count(); d++) { if (j4 == null) continue; if (c > 0) { j4 = j4.Next; if (j4 == null) continue; } var s = j4 as JProperty; if (s == null) { continue; } // s null check Console.WriteLine("FOR 3 = " + a.ToString() + "," + b.ToString() + "," + c.ToString() + "," + d.ToString() + " --- " + s.Name); // DO STUFF HERE. // ... } // for d - j3 } // for c - j2 } // for b - j1 } // for a - original JObject