2016-07-25 72 views
0

任何人都可以提供一些建议,也许有一个代码片段,使用C#和json.net来阅读一些嵌套的JSON? 我的json下面使用JSONLint验证了良好的json。 我打了一个解析json的障碍,我无法进入嵌套在根中的第3,第4,第6和第8个值。嵌套的JSON使用C#NewtonSoft

[{ 
"interactionType": "MathEditorInteraction", 
"interactionId": "08506178-22ba-4fa7-a490-c785716f10dc", 
"value": "blah blah blah" 
}, 
{ 
"interactionType": "MathEditorInteraction", 
"interactionId": "1134871f-980e-4138-9598-0d4bf480aa97", 
"value": "my first value" 
}, 
{ 
"interactionType": "CanvasInteraction", 
"interactionId": "89cd7bec-d0e8-4111-8442-f2ab95a1410b", 
"value": "my second value" 
}, 
{ 
"interactionType": "FillInBlankInteraction", 
"interactionId": "7e9350b4-fb85-4f12-869e-227f99f77a73", 
"value": "{\"results\":[{\"id\":\"1ac6770e-2093-4b7c-b595-789be8ee6efb\",\"value\":\"my third value\"}]}" 
}, 
{ 
"interactionType": "FillInBlankInteraction", 
"interactionId": "6f1ca6b7-3178-44a7-b8e9-e82d8c51d1fd", 
"value": "{\"results\":[{\"id\":\"b7e92fd2-9c7a-4f71-88f9-e7d43e3179b7\",\"value\":\"my fourth value\"}]}" 
}, 
{ 
"interactionType": "TextBoxInteraction", 
"interactionId": "284c43f9-a268-4295-b96d-bc2f6dc30f0e", 
"value": "my fifth value" 
}, 
{ 
"interactionType": "FillInBlankInteraction", 
"interactionId": "544b9907-139a-4c78-9671-502153be2697", 
"value": "{\"results\":[{\"id\":\"f4e1ba6d-61dd-4eed-9c6f-dafc2701c161\",\"value\":\"my sixth value\"}]}" 
}, 
{ 
"interactionType": "TextBoxInteraction", 
"interactionId": "c0a5a1f0-2cae-42fd-8726-0ad36c11f413", 
"value": "my seventh value" 
}, 
{ 
"interactionType": "FillInBlankInteraction", 
"interactionId": "ef6a7b62-8a7b-4b7f-b876-0d78ee6c4c87", 
"value": "{\"results\":[{\"id\":\"af39469e-c041-4889-9e28-61a438cf56a3\",\"value\":\"my eight value\"}]}" 
}, 
{ 
"interactionType": "TextBoxInteraction", 
"interactionId": "f04de5b5-8a29-4200-a886-15f7dbd575b6", 
"value": "my nineth value" 
}] 

那时,我已经使用一些C#:

JArray token = JArray.Parse(response); // response = json string above 
for (int i = 0; i < token.Count; i++) 
{ 
    String value = token[i]["value"].ToString(); 
} 

我可以用JSON我消耗惊讶...它可能有正数嵌套值...的目的我的代码是用“值”字符串到达​​最底层的孩子。 有没有办法看一个令牌[我] [“一些字符串”],看看它是否包含JArray或JObject继续解析?

从蒂莫西的建议编辑,我能够输出的价值。差不多了。

static string json2 = @"[{""interactionType"": ""MathEditorInteraction"",""interactionId"": ""08506178-22ba-4fa7-a490-c785716f10dc"",""value"": ""blah blah blah""},{""interactionType"": ""MathEditorInteraction"",""interactionId"": ""1134871f-980e-4138-9598-0d4bf480aa97"",""value"": ""my first value""},{""interactionType"": ""CanvasInteraction"",""interactionId"": ""89cd7bec-d0e8-4111-8442-f2ab95a1410b"",""value"": ""my second value""},{""interactionType"": ""FillInBlankInteraction"",""interactionId"": ""7e9350b4-fb85-4f12-869e-227f99f77a73"",""value"": ""{\""results\"":[{\""id\"":\""1ac6770e-2093-4b7c-b595-789be8ee6efb\"",\""value\"":\""my third value\""}]}""},{""interactionType"": ""FillInBlankInteraction"",""interactionId"": ""6f1ca6b7-3178-44a7-b8e9-e82d8c51d1fd"",""value"": ""{\""results\"":[{\""id\"":\""b7e92fd2-9c7a-4f71-88f9-e7d43e3179b7\"",\""value\"":\""my fourth value\""}]}""},{""interactionType"": ""TextBoxInteraction"",""interactionId"": ""284c43f9-a268-4295-b96d-bc2f6dc30f0e"",""value"": ""my fifth value""},{""interactionType"": ""FillInBlankInteraction"",""interactionId"": ""544b9907-139a-4c78-9671-502153be2697"",""value"": ""{\""results\"":[{\""id\"":\""f4e1ba6d-61dd-4eed-9c6f-dafc2701c161\"",\""value\"":\""my sixth value\""}]}""},{""interactionType"": ""TextBoxInteraction"",""interactionId"": ""c0a5a1f0-2cae-42fd-8726-0ad36c11f413"",""value"": ""my seventh value""},{""interactionType"": ""FillInBlankInteraction"",""interactionId"": ""ef6a7b62-8a7b-4b7f-b876-0d78ee6c4c87"",""value"": ""{\""results\"":[{\""id\"":\""af39469e-c041-4889-9e28-61a438cf56a3\"",\""value\"":\""my eight value\""}]}""},{""interactionType"": ""TextBoxInteraction"",""interactionId"": ""f04de5b5-8a29-4200-a886-15f7dbd575b6"",""value"": ""my ninth value""}]"; 

var x = JsonConvert.DeserializeObject<Interaction[]>(json2); 
for (int i = 0; i < x.Length; i++) 
{ 
if (x[i].value.Contains("[{")) 
    { 
     var v = JsonConvert.DeserializeObject<Nested>(x[i].value); 
     Console.WriteLine(v.results[0].value); 
    } 
else 
    { 
     Console.WriteLine(x[i].value); 
    }  
} 

控制台输出:

blah blah blah 
my first value 
my second value 
my third value 
my fourth value 
my fifth value 
my sixth value 
my seventh value 
my eight value 
my ninth value 

仍然停留在实际检测比第一级更深层的阵列。 你可以看到我的黑客寻找“[{”这不是首选。

编辑:KUDOS Jens帮助我到达我今天需要的解决方案。请参阅下面的评论以获得完整的解释

回答

2

您可以到JToken.Type反应,如果你不希望进入反序列化对象很容易反序列容易生成模型类。 我实际上主要是在J#中使用C#中的动态方式工作,我从来没有将其反序列化为强类型,这主要是因为我们使用后端,数据结构由客户端定义,我们需要能够处理更多更动态的数据。

https://dotnetfiddle.net/awUSGT

dynamic arr = JArray.Parse(JSON); // response = json string above 

    foreach (dynamic token in arr) 
    { 
     JTokenType type = ((JToken)token.value).Type; 

     switch (type) 
     { 
      case JTokenType.String: 
       Console.WriteLine(token.value); 
       break; 

      case JTokenType.Object: 
       Console.WriteLine(token.value.results.Last.value); 
       break; 
     } 
    } 

注意,对于之前8.x的或9.x中(不记得,当我张贴修复)一些铸造JToken时,上面会抛出异常。

那么可以改为做:

dynamic arr = JArray.Parse(JSON); // response = json string above 

    foreach (JObject token in arr) 
    { 
     dynamic value = token["value"]; 
     switch (token["value"].Type) 
     { 
      case JTokenType.String: 
       Console.WriteLine(value); 
       break; 

      case JTokenType.Object: 
       Console.WriteLine(value.results.Last.value); 
       break; 
     } 
    } 

现在作为一个最后一点,我用来美化您的JSON的工具似乎剥去一些转义为你的价值观。

我不知道是否有意将您的嵌入式JSON作为字符串(序列化JSON),如果是这样,您需要找到一种方法来发现并解析它。

松动/轻松的方式可以是:

dynamic arr = JArray.Parse(JSON); // response = json string above 

    foreach (dynamic token in arr) 
    { 
     string tokenvalue = (string) token.value; 
     JToken value = Regex.IsMatch(tokenvalue, "^\\{.*\\}$") 
      ? JToken.Parse(tokenvalue) 
      : token.value; 
     switch (value.Type) 
     { 
      case JTokenType.String: 
       Console.WriteLine(value); 
       break; 

      case JTokenType.Object: 
       Console.WriteLine(((dynamic)value).results.Last.value); 
       break; 
     } 
    } 

因为我不知道你的“递归嵌套”究竟如何看,这是很难猜测,但是沿着线的东西:

public static void Main() 
{ 
    dynamic arr = JArray.Parse(JSON); // response = json string above 

    foreach (dynamic token in arr) 
    { 
     JToken value = ExtractValue(token); 
     Console.WriteLine(value); 
    } 
} 

private static JToken ExtractValue(dynamic token) 
{ 
    string tokenvalue = (string) token.value; 
    JToken value = Regex.IsMatch(tokenvalue, "^\\{.*\\}$") 
     ? JToken.Parse(tokenvalue) 
     : token.value; 

    switch (value.Type) 
    { 
     case JTokenType.String: 
      return value; 

     case JTokenType.Object: 
      return ExtractValue(((dynamic) value).results.Last); 

     default: 
      throw new InvalidOperationException("Could not extract data, unknown json construct."); 
    } 
} 

也许吧。

+0

Jens,当你的代码看到一个JTokenType.Object而不是嵌套值时,你的代码将输出完整的子数组。但非常接近我所追求的。 –

+0

宽松/放松的方法有效,但只有一层嵌套。我需要找到一种方法来动态检测嵌套并应用您的逻辑。递归的东西,我仍然在思索...如果你有任何建议?我的大脑正朝着do/while循环内的某种try/catch转向,这可能不是最好的选择 –

+0

既然你没有提供这个深层嵌套看起来如何的例子,它不容易碰到钉子正确,但我已经添加了一个至少可以激发的例子。 – Jens

0

尝试使用这样的:JsonConvert.DeserializeObject<Interaction[]>(yourJson);

其中Interaction是:

public class Interaction 
{ 
    public string interactionType {get;set;} 
    public string interactionId {get;set;} 
    public string value {get;set;} 
} 

然后,对于有一个嵌套的JSON的那些,你就可以简单地解析他们的value属性如下所示:

public class Nested 
{ 
    public Result[] results {get;set;} 
} 

public class Result 
{ 
    public string id {get;set;} 
    public string value {get;set;} 
} 

然后分析它是这样的:

var v = JsonConvert.DeserializeObject<Nested>(x[8].value); 
+0

非常有帮助蒂莫西。通过一些细微的修改,我能够从您的示例中获得原始值。 –

0

可以使用this service

在这种模式下,你可以使用Newtonsoft的Json