[英]How do I parse a JSON object in C# when I don't know the key in advance?
I have some JSON data that looks like this:我有一些看起来像这样的 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
}
}
How can I parse this using JSON.net?如何使用 JSON.net 解析它? I can first do this:
我可以先这样做:
JObject jFoo = JObject.Parse(data);
I need to be able to iterate over each object in this list.我需要能够遍历此列表中的每个对象。 I would like to be able to do something like this:
我希望能够做这样的事情:
foreach (string ref_id in (string)jFoo["ref_id"]) {...}
or或者
foreach (JToken t in jFoo.Descendants())
{
Console.WriteLine((string)t["ref_id"]);
}
but of course that doesn't work.但这当然行不通。 All the examples work great if you know the key while writing your code.
如果您在编写代码时知道密钥,那么所有示例都可以很好地工作。 It breaks down when you don't know the key in advance.
当您事先不知道密钥时,它就会崩溃。
It's doable;这是可行的; this works but it's not elegant.
这有效,但并不优雅。 I'm sure there's a better way.
我确定有更好的方法。
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);
}
}
}
}
Prints:印刷:
id:910719 type:asdf ref_id:7568 id:910721 type:asdf ref_id:7568 id:910723 type:asdf ref_id:7568
You can iterate over the child objects with a simple LINQ query like this:您可以使用一个简单的 LINQ 查询来迭代子对象,如下所示:
JObject jFoo = JObject.Parse(json);
foreach (JObject obj in jFoo.Properties().Select(p => p.Value))
{
Console.WriteLine("id: " + obj["id"]);
Console.WriteLine("type: " + obj["type"]);
Console.WriteLine("ref_id: " + obj["ref_id"]);
}
Fiddle: https://dotnetfiddle.net/fwINPa小提琴: https : //dotnetfiddle.net/fwINPa
Or if you just want all the ref_id
values, you can do something like this:或者,如果您只想要所有
ref_id
值,您可以执行以下操作:
string[] refIds = jFoo.Properties()
.Select(p => (string)p.Value["ref_id"])
.ToArray();
Console.Write(string.Join("\r\n", refIds));
Fiddle: https://dotnetfiddle.net/twOuVY小提琴: https : //dotnetfiddle.net/twOuVY
I'm using Json.NET and I wrote a quick way where you can print out all of the keys and corresponding values using a recursive method.我正在使用 Json.NET 并编写了一种快速方法,您可以使用递归方法打印出所有键和相应的值。
var o = JObject.Parse(YourJsonString);
getAllProperties(o); //call our recursive method
Then you can use this recursive method to get all the Properties and their values然后你可以使用这个递归方法来获取所有的属性和它们的值
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);
}
}
Have you considered using JavascriptSerializer?您是否考虑过使用 JavascriptSerializer?
you could try do something like this:你可以尝试做这样的事情:
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 http://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.aspx
Konstantin's solution will work but if you want a list of Id's do the same thing and instead of the Console.Writeln() use the following 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"]);
}
I found TrueWill's answer worked, but I wanted to avoid foreach and try getting a simple for loop to work for the sake of speed.我发现 TrueWill 的答案有效,但我想避免 foreach 并尝试使用简单的 for 循环来提高速度。 My results were certainly what could be described as ugly at best.
我的结果肯定是充其量只能被描述为丑陋的。 Here they are in case they are useful for anyone.
以防万一它们对任何人都有用。 (I've left in WriteLine for the sake of being able to see things a bit easier.)
(为了能够更容易地看到事情,我离开了 WriteLine。)
Note that this will not work for some JSON and isn't perfectly generic.请注意,这不适用于某些 JSON 并且不是完全通用的。 Some null checks could be done better, etc.
一些空检查可以做得更好,等等。
// 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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.