【问题标题】:How to update property value in JSON string?如何更新 JSON 字符串中的属性值?
【发布时间】:2017-09-26 02:20:09
【问题描述】:

下面是我的 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:如果infoname属性是null,那么我想将infoFlag更新为true,否则false如果是not null

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

注意:我不想反序列化然后根据以上两个规则更新属性,因为我的 JSON 有很多我不想为其创建类的属性,所以我寻找无需反序列化类即可工作的东西。

这就是我尝试的方式:

string json = "MyJson";
var temp =  JArray.Parse(json);
temp.Descendants()
    .OfType<JProperty>()
json = temp.ToString();

但是在这里我不知道如何递归地遍历我的 JSON;如您所见,我有如下递归结构:

Node-1
    Node-1-1
       Node-1-1-1

【问题讨论】:

  • 您可以deserialize without having to declare classes。 alertnative 是根本不反序列化,但是你必须编写一个非常智能的解析器。
  • @GolezTrol 提出这个问题的主要目的是如何在不反序列化到类的情况下定位和更新属性值。我非常清楚如何将 json 字符串反序列化为动态对象 :)
  • 那你为什么说“有很多我不想为其创建类的属性”。使用动态对象,您可以做到这一点。 JArray.Parse 你也反序列化。如果你想替换属性而不反序列化,你将不得不坚持String.Replace 或一些正则表达式魔法,但我敢肯定你不想走那条路。
  • @GolezTrol 可以反序列化到任何动态对象,但我只是说我不想反序列化到任何类,因为我不想创建类来处理这个反序列化。此外,我我正在努力在反序列化为动态对象后操纵这些属性。

标签: c# json


【解决方案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();

【讨论】:

  • 这真的很漂亮:)
  • 这行得通。非常感谢你,请像往常一样继续提供这样的天才和精彩的答案:)
【解决方案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": []
          }
        ]
      }
    ]
  }
]

【讨论】:

  • 赞成您为帮助我所做的努力。感谢:)
猜你喜欢
  • 2021-12-10
  • 2016-05-20
  • 1970-01-01
  • 2021-02-23
  • 1970-01-01
  • 1970-01-01
  • 2016-06-13
  • 1970-01-01
  • 2020-09-08
相关资源
最近更新 更多