2017-07-14 69 views
0

我打电话给webservice,它以下面的格式返回json中的响应。在c中解析一个动态变化的json文件#

{ 
    "parent": 
    { 
     "child": { 
     "key1": value1, 
     "key2": value2 
     } 
    } 
} 

以上的回应是当父母只有一个孩子。但是,当有在母体一个以上的孩子,则响应如下所示:

{ 
    "parent": [ 
    { 
     "child": { 
     "key1": "value1", 
     "key2": "value2" 
     } 
    }, 
    { 

     "child": { 
     "key1": "value1", 
     "key2": "value2" 
     } 
    } 
    ] 
} 

因此,当有一个以上的子元素,父是JArray并且当仅存在子元素,父是JObject。

现在我很难动态解析子元素的内容,因为它在JObject时会抛出索引错误。

有人可以解释我们如何解析JObject和JArray期间的内容。

目前我正在检查父标记,因为它是否是JObject/JArray和相应的解析,但这是一个漫长而乏味的过程。

有没有其他方法相同。

以下是代码,我现在使用的

if(jsonfile["parent"].getType() == "JObject") 
{ 
    string value1 = (string)jsonfile["parent"]["child"]["key1"] 
} 
else 
{ 
    string value1 = (string)jsonfile["parent"][0]["child"]["key1"]; 
} 

是否有任何其他方法,我们可以得到值1,不检查父是否JObject或JArray?

+0

您标记json.net,如果你是确实使用它,将json转换为对象并使用该对象会更容易[反序列化](http://www.newtonsoft.com/json/help/html/DeserializeObject.htm)。也看到这个问题:https://stackoverflow.com/questions/4535840/deserialize-json-object-into-dynamic-object-using-json-net – Esko

+0

没有childX属性不会改变。我纠正了错误。 – Dipumon

+0

你想解析你的JSON到C#类或? –

回答

0

你可以引入一个扩展方法,如

public static class JsonExtensions 
{ 
    public static IEnumerable<JToken> SingleOrArrayItems(this JToken source) 
    { 
     if (source == null || source.Type == JTokenType.Null) 
      return Enumerable.Empty<JToken>(); 
     IEnumerable<JToken> arr = source as JArray; 
     return arr ?? new[] { source }; 
    } 
} 

然后执行:

var child = jsonfile["parent"].SingleOrArrayItems().FirstOrDefault(); 
var value1 = child == null ? null : child.SelectToken("child.key1"); 

或者你可以使用SelectTokens()与服用可选数组索引的地方JSONPath递归下降操作..

var value1 = jsonfile.SelectTokens("parent..child.key1").FirstOrDefault(); 

样品fiddle

(关于如何处理这种多态JSON的出现往往问题;例如见How to handle both a single item and an array for the same property using JSON.net一种方式来反序列化JSON像这样固定的POCO类型)