解析动态JSON

  • 本文关键字:JSON 动态 json json.net
  • 更新时间 :
  • 英文 :


JSON是这样的:

{
    "status": {
        "code": 0,
        "message": "OK"
    },
    "data": {
        "_idtype": "cusip",
        "_id": "00768Y883",
        "api": {
            "_name": "PortfolioBreakdownsRaw",
            "PortfolioDate": "2015-10-12",
            "GlobalBondSuperSectorLongSalePositionBreakdown": [
                {
                    "Name": "Municipal",
                    "Value": "0.57842"
                },
                {
                    "Name": "Corporate",
                    "Value": "1.79649"
                },
                {
                    "Name": "Securitized",
                    "Value": "5.29493"
                },
                {
                    "Name": "Cash & Equivalents",
                    "Value": "166.20776"
                }
            ],
            "GlobalBondSuperSectorShortSalePositionBreakdown": [
                {
                    "Name": "Government",
                    "Value": "0.90557"
                }
            ]
        }
    }
}

我可以很容易地得到响应的api部分:

var jObject = JObject.Parse(json);
var api = jObject["data"]["api"];
从这里开始,我不知道是否有任何数组将包含在响应中。最终的目标是创建一个解析器,它将能够获得数组名称(GlobalBondSuperSectorShortSalePositionBreakdown)和它可能包含的尽可能多的键值对行,而不需要事先知道名称(GlobalBondSuperSectorShortSalePositionBreakdown)。

我似乎找不到一个好方法来循环对象,确定在api级别有数组,然后迭代这些数组以获得值。

下面是一个例子。在这段代码中,api变量保存着一个JObject,因此我们可以遍历它的属性。从那里,我们查看每个属性值的Type,看看它是否是一个数组。如果是,那么我们可以遍历该数组以获得其中的JObjects,并提取我们期望在其中找到的NameValue值。这有帮助吗?

var jObject = JObject.Parse(json);
var api = jObject["data"]["api"];
foreach (JProperty prop in api.Children<JProperty>())
{
    JToken value = prop.Value;
    if (value.Type == JTokenType.Array)
    {
        Console.WriteLine(prop.Name + ": ");
        foreach (JObject jo in value.Children<JObject>())
        {
            Console.WriteLine("   " + jo["Name"] + ": " + jo["Value"]);
        }
    }
    else
    {
        Console.WriteLine(prop.Name + ": " + value);
    }
}
输出:

_name: PortfolioBreakdownsRaw
PortfolioDate: 2015-10-12
GlobalBondSuperSectorLongSalePositionBreakdown:
   Municipal: 0.57842
   Corporate: 1.79649
   Securitized: 5.29493
   Cash & Equivalents: 166.20776
GlobalBondSuperSectorShortSalePositionBreakdown:
   Government: 0.90557

小提琴:https://dotnetfiddle.net/XyoXQy

使用Linq可以很好地处理Json.net:

下面是这段代码的一个易于阅读的版本,它将从api元素下的JArray属性中创建两个字典:
var api = jObject["data"]["api"];
var arrays = api.Cast<JProperty>().Where(o => o.Value.Type == JTokenType.Array).Select(token => token.Value).ToArray();
var dictionaries = new List<Dictionary<string, string>>();
foreach (var array in arrays)
{
    var dictionary = array.ToDictionary(token => token["Name"].Value<string>(), token => token["Value"].Value<string>());
    dictionaries.Add(dictionary);
}

选择:

相同的东西,但更短,更紧凑的版本:

var api = jObject["data"]["api"];
var dictionaries = api
    .Cast<JProperty>()
    .Where(o => o.Value.Type == JTokenType.Array)
    .Select(token => token.Value)
    .Select(array => array.ToDictionary(token => token["Name"].Value<string>(), token => token["Value"].Value<string>()));

相关内容

  • 没有找到相关文章

最新更新