json.net获取所有json令牌和readout特定属性

时间:2018-01-17 09:26:59

标签: .net json token json-deserialization

我有以下json文件:

{
  "GuiElement0": {
    "gHeight": "50",
    "gID": "0",
    "gY": "80"
  },
  "GuiElement1": {
    "gFile": "",
    "gID": "0",
    "gStyle": "2",
    "gX": "130",
    "gY": "240"
  },
  "GuiElement2": {
    "gThickness": "1",
    "gID": "0",
    "gStyle": "3",
    "gX": "150",
    "gY": "20"
  }
}

现在我想迭代这样的单个元素:

JObject json = JObject.Parse(file.ReadToEnd());
foreach (JToken token in json.Children())
{
    if(JObject.Parse(token.ToString()).GetValue("gID").ToString() == "0" )
    {
        MessageBox.Show(JObject.Parse(token.ToString()).Property("gID").ToString());
    }
}

不幸的是,这不能按预期工作。 我的目标是读出每个令牌的gID,然后处理每个元素seperatley。

如果我有了ID,那么我将对json进行dezerialize

"gThickness": "1",
"gID": "0",
"gStyle": "3",
"gX": "150",
"gY": "20"
像这样:

(GuiElement)JsonConvert.DeserializeObject<GuiBar>(token.ToString());

如果有人能指出我的错误,那就太好了。 谢谢!

2 个答案:

答案 0 :(得分:0)

我找到了解决方案:

foreach (JProperty prop in json.Children())
{

    JToken value = prop.Value;
    if(value.Type == JTokenType.Object)
    {
        MessageBox.Show(((JObject)value).GetValue("gID").ToString());
    }

}

答案 1 :(得分:0)

在循环中,token获取子json属性的值。例如,在第一次迭代时,它将是GuiElement0属性:

"GuiElement0": {
    "gHeight": "50",
    "gID": "0",
    "gY": "80"
}

您无法在此类媒体上调用JObject.Parse(),因为它不是有效的JSON(它只是其中的一部分)。

无论如何,使用相同JSON或其部分进行多次解析并不是一个好主意,这样的解决方案将具有非常差的性能。相反,只需将迭代的孩子投射到JProperty并通过JProperty.Value访问当前元素:

foreach (JProperty currProperty in json.Children().OfType<JProperty>())
{
    JToken currElement = currProperty.Value;
    // ...

此处currElement将采用GuiElement属性的值:

{
    "gHeight": "50",
    "gID": "0",
    "gY": "80"
}

您可以访问特定的子属性,以便通过JToken.SelectToken()进行比较。我还建议使用强类型JToken.Value<T>属性来提取值:

JToken gIdValue = currElement.SelectToken("gID");
if (gIdValue.Value<int>() == 0)
{
  // ...

最后,您可以使用JToken.ToObject<T>()调用反序列化对象。这将避免额外的JSON解析。

以下是最终代码:

foreach (JProperty currProperty in json.Children().OfType<JProperty>())
{
    JToken currElement = currProperty.Value;
    JToken gIdValue = currElement.SelectToken("gID");
    if (gIdValue.Value<int>() == 0)
    {
        var bar = currElement.ToObject<GuiBar>();
    }
}
相关问题