简体   繁体   English

当我事先不知道密钥时,如何在 C# 中解析 JSON 对象?

[英]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.

相关问题 当我不知道键和属性没有名称时,如何在 C# 中解析 JSON 对象? - How do I parse a JSON object in C# when I don't know key and properties don't have names? 如何比较两个 IEnumerable<T> 在 C# 中,如果我不知道实际的对象类型? - How to compare two IEnumerable<T> in C# if I don't know the actual object type? 如果我不知道GUID,如何使用c#在Microsoft CRM上检索一条记录? - How do I retrieve a single record on Microsoft CRM using c# if I don't know the GUID? 如何解析 c# 中的 JSON? - How do I parse JSON in c#? 如果我不知道c#中的结构,如何访问对象的内容? - How to access contents of Object If I don't know the structure in c#? 我不知道如何使用 C# ASP.NET 进行 Soap 请求 - I don't know how to do a Soap Request using C# ASP.NET 当我不知道原始编码时,如何在 c# 中将文件转换为 unix 或 windows - How to convert file to unix or windows in c# when I don't know the original encoding 我如何使用Newtonsoft.json将JSON字符串正确解析为C#中的对象? - How do I correctly parse a JSON string using Newtonsoft.json to an object in C#? 我需要做一个 python 项目,但我知道 C# 并且不知道如何转换它 - I need to make a python project but I know C# and don't know how to convert it 我如何使用JSON.net从c#中的JSON文件中获取密钥及其对象? - How do I get the key and it's object from a JSON file in c# using JSON.net?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM