【问题标题】:Accessing all items in the JToken访问 JToken 中的所有项目
【发布时间】:2013-05-28 14:47:28
【问题描述】:

我有一个这样的 json 块:

{
    "ADDRESS_MAP":{

        "ADDRESS_LOCATION":{
            "type":"separator",
            "name":"Address",
            "value":"",
            "FieldID":40
        },
        "LOCATION":{
            "type":"locations",
            "name":"Location",
            "keyword":{
                "1":"LOCATION1"
            },
            "value":{
                "1":"United States"
            },
            "FieldID":41
        },
        "FLOOR_NUMBER":{
            "type":"number",
            "name":"Floor Number",
            "value":"0",
            "FieldID":55
        },
        "self":{
            "id":"2",
            "name":"Address Map"
        }
    }
}

如何获取此令牌包含的所有关键项目。例如,从上面的代码中,我想要 "ADRESS_LOCATION" 、 "LOCATION"、"FLOOR_NUMBER" 和 "self"。

【问题讨论】:

    标签: c# json json.net


    【解决方案1】:

    您可以将JToken 转换为JObject,然后使用Properties() 方法获取对象属性列表。从那里,您可以很容易地获得名称。

    类似这样的:

    string json =
    @"{
        ""ADDRESS_MAP"":{
    
            ""ADDRESS_LOCATION"":{
                ""type"":""separator"",
                ""name"":""Address"",
                ""value"":"""",
                ""FieldID"":40
            },
            ""LOCATION"":{
                ""type"":""locations"",
                ""name"":""Location"",
                ""keyword"":{
                    ""1"":""LOCATION1""
                },
                ""value"":{
                    ""1"":""United States""
                },
                ""FieldID"":41
            },
            ""FLOOR_NUMBER"":{
                ""type"":""number"",
                ""name"":""Floor Number"",
                ""value"":""0"",
                ""FieldID"":55
            },
            ""self"":{
                ""id"":""2"",
                ""name"":""Address Map""
            }
        }
    }";
    
    JToken outer = JToken.Parse(json);
    JObject inner = outer["ADDRESS_MAP"].Value<JObject>();
    
    List<string> keys = inner.Properties().Select(p => p.Name).ToList();
    
    foreach (string k in keys)
    {
        Console.WriteLine(k);
    }
    

    输出:

    ADDRESS_LOCATION
    LOCATION
    FLOOR_NUMBER
    self
    

    【讨论】:

    • 迭代 JObject 容器而不是转换为 .NET 类型会减少代码并可能获得更好的性能。我添加了一个答案来补充这个显示该方法的答案。
    • 或者 - 如果你知道你想要什么属性: var location = inner.Property("LOCATION").Value;
    【解决方案2】:

    除了接受的答案之外,我想给出一个答案,说明如何直接迭代 Newtonsoft 集合。它使用的代码更少,我猜它更有效,因为它不涉及转换集合。

    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    //Parse the data
    JObject my_obj = JsonConvert.DeserializeObject<JObject>(your_json);
    
    foreach (KeyValuePair<string, JToken> sub_obj in (JObject)my_obj["ADDRESS_MAP"])
    {
        Console.WriteLine(sub_obj.Key);
    }
    

    我自己开始这样做是因为 JsonConvert 会自动将嵌套对象反序列化为 JToken(我认为是 JObject、JValue 或 JArray)。

    我认为解析的工作原理如下:

    • 每个对象都被抽象为一个 JToken

    • 在您期望字典的地方转换为 JObject

    • 如果 JToken 代表一个终端节点并且是一个值,则转换为 JValue

    • 如果 JArray 是数组,则转换为 JArray

    • JValue.Value 为您提供所需的 .NET 类型

    【讨论】:

    • 对项目符号解析原理非常有帮助的解释,谢谢。
    【解决方案3】:

    如果您知道您收到的 json 的结构,那么我建议您使用一个类结构来反映您在 json 中收到的内容。

    那么你可以这样称呼它......

    AddressMap addressMap = JsonConvert.DeserializeObject<AddressMap>(json);
    

    (其中 json 是包含相关 json 的字符串)

    如果您不知道收到的 json 格式,那么它会变得有点复杂,您可能需要手动解析它。

    查看http://www.hanselman.com/blog/NuGetPackageOfTheWeek4DeserializingJSONWithJsonNET.aspx了解更多信息

    【讨论】:

      猜你喜欢
      • 2023-03-22
      • 2015-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-18
      相关资源
      最近更新 更多