How do I parse a JSON object in C# when I don't know the key in advance?

删除回忆录丶 提交于 2019-12-17 09:51:21

问题


I have some JSON data that looks like this:

{
  "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? 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.


回答1:


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



回答2:


You can iterate over the descendants with a simple LINQ query like this:

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"]);
}

Similarly, if you want just the ref_id values, you can get those like this:

foreach (string refId in jFoo.Properties().Select(p => p.Value["ref_id"]))
{
    Console.WriteLine(refId);
}



回答3:


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.

      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);
        }
    }



回答4:


Have you considered using 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




回答5:


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

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"]);
}



回答6:


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. 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.)

Note that this will not work for some JSON and isn't perfectly generic. 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


来源:https://stackoverflow.com/questions/8855494/how-do-i-parse-a-json-object-in-c-sharp-when-i-dont-know-the-key-in-advance

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!