2015-10-14 54 views
1

我有JSON,看起来像这样:JSON.net解析

{ 
    "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级别的数组,然后遍历这些来获取值。

任何帮助,将不胜感激。

+0

你想建立一个字典列表哪些是下'api'数组中元素的元素,对吗?排除不是数组的所有元素,比如'_name'和'PortfolioDate',并且假设所有这些数组都是键/值对,并且不会有不符合该条件的数组,那么它是正确的吗? –

回答

0

下面是一个例子。在此代码中,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

+0

这很好,非常感谢。我的答案中有一些零碎点,但我无法把它们放在一起。谢谢! – kwcolson98

+0

没问题;乐意效劳。 –

0

使用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>()));