我有一些看起来像这样的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);
我需要能够遍历此列表中的每个对象。我希望能够做到这样的事情:
foreach (string ref_id in (string)jFoo["ref_id"]) {...}
或
foreach (JToken t in jFoo.Descendants())
{
Console.WriteLine((string)t["ref_id"]);
}
但当然不起作用。如果您在编写代码时知道密钥,那么所有示例都能很好地工作。如果您事先不知道密钥,它就会崩溃。
答案 0 :(得分:21)
这是可行的;这可行,但它并不优雅。我确信有更好的方法。
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 type:asdf ref_id:7568 id:910721 type:asdf ref_id:7568 id:910723 type:asdf ref_id:7568
答案 1 :(得分:3)
您可以使用简单的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);
}
答案 2 :(得分:3)
我正在使用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);
}
}
答案 3 :(得分:1)
你考虑过使用JavascriptSerializer吗?
你可以尝试这样做:
JavaScriptSerializer serializer = new JavaScriptSerializer();
var foo = serializer.Deserialize<Dictionary<string, Dictionary<string, string>>>(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
答案 4 :(得分:-1)
Konstantin的解决方案可行,但如果你想要Id的列表做同样的事情而不是Console.Writeln()使用以下
List<string> list = new List<string>();
JavaScriptSerializer serializer = new JavaScriptSerializer();
var foo = serializer.Deserialize<Dictionary<string, Dictionary<string, string>>>(data);
foreach(var item in foo)
{
list.Add(item.Value["ref_id"]);
}
答案 5 :(得分:-2)
我发现TrueWill的答案有效,但我想避免使用foreach并尝试为了速度而使一个简单的for循环工作。我的结果当然可以说是丑陋的。在这里他们是对任何人都有用的。 (为了能够更容易地看到事情,我在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