如何更新JSON字符串中的属性值?

时间:2017-09-21 08:10:42

标签: c# json

以下是我的JSON:

[
  {
    "name": "Node-1",
    "flag": true,
    "myObj": {
      region: {
        info: {
          name: null,
          infoFlag: false,

        }
      }
    },
    "nodes": [
      {
        "name": "Node-1-1",
        "flag": true,
        "myObj": {
          region: {
            info: {
              name: "abc",
              infoFlag: false,

            }
          }
        },
        "nodes": [
          {
            "name": "Node-1-1-1",
            "flag": true,
            "myObj": {
              region: {
                info: {
                  name: "xyz",
                  infoFlag: false,

                }
              }
            },
            "nodes": [

            ]
          }
        ]
      }
    ]
  }
]

我想使用以下规则更新上述JSON字符串的两个属性:

举报:我想盲目地将此属性更新为false

infoFlag:如果name的{​​{1}}属性为info,那么我想将null更新为infoFlag其他{{ 1}}如果是true

因此,在使用这些规则更新我的JSON之后,我希望将JSON作为字符串。

注意:我不想反序列化然后根据上述两条规则更新属性,因为我的JSON有很多属性,我不想创建类,所以我是寻找可以在没有反序列化的情况下工作的东西。

这就是我尝试这样做的方式:

false

但是我在这里并没有像递归地遍历我的JSON那样;你可以看到我有如下的递归结构:

not null

2 个答案:

答案 0 :(得分:2)

如果我已经理解了你的需求,那么这段代码非常冗长,而且不那么优雅但是很有效:

    JArray temp =  JArray.Parse(json);

    foreach (JToken tk in temp.Descendants())
    {
        if (tk.Type == JTokenType.Property)
        {
            JProperty p = tk as JProperty;

            if (p.Name == "flag")
            {
                if ((bool)p.Value.ToObject(typeof(bool)) == true)
                    p.Value = false;
            }

            if ((p.Name == "info") && p.HasValues)
            {
                bool flag = false;

                foreach (JToken tkk in p.Descendants())
                {
                    if (tkk.Type == JTokenType.Property)
                    {
                        JProperty pp = tkk as JProperty;

                        if ((pp.Name == "name") && (pp.Value.Type == JTokenType.Null))
                        {
                            flag = true;
                        }

                        if ((pp.Name == "infoFlag"))
                        {
                            pp.Value = (flag == true) ? true : false;
                        }
                    }
                }
            }
        }
    }

    json = temp.ToString();

这是结果输出:

[
  {
    "name": "Node-1",
    "flag": false,
    "myObj": {
      "region": {
        "info": {
          "name": null,
          "infoFlag": true
        }
      }
    },
    "nodes": [
      {
        "name": "Node-1-1",
        "flag": false,
        "myObj": {
          "region": {
            "info": {
              "name": "abc",
              "infoFlag": false
            }
          }
        },
        "nodes": [
          {
            "name": "Node-1-1-1",
            "flag": false,
            "myObj": {
              "region": {
                "info": {
                  "name": "xyz",
                  "infoFlag": false
                }
              }
            },
            "nodes": []
          }
        ]
      }
    ]
  }
]

答案 1 :(得分:1)

Json.NET允许您将表示JSON内容的内部对象视为dynamic,这使得有问题的任务不会比使用常规类型对象更难。

唯一一个棘手的问题是递归对象结构(nodes数组),但这不是JSON或dynamic特定问题,可以通过多种方式解决 - 明显的递归方法或者我的首选树展平枚举(我对How to flatten tree via LINQ?的回答中的Expand方法)。

话虽如此,解决方案可能是这样的:

var array = JArray.Parse(json);
var nodes = array.Cast<dynamic>().Expand(x => x.nodes);
foreach (var node in nodes)
{
    node.flag = true;
    var info = node.myObj.region.info;
    info.infoFlag = (info.name == null);
}
var newJson = array.ToString();