代码之家  ›  专栏  ›  技术社区  ›  Learning-Overthinker-Confused

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

  •  2
  • Learning-Overthinker-Confused  · 技术社区  · 7 年前

    [
      {
        "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 .

    如果 name info null 然后我想更新 infoFlag true 其他的 如果是的话 not null .

    注: 我不想反序列化然后根据以上两个规则更新属性,因为我的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
    
    2 回复  |  直到 7 年前
        1
  •  2
  •   Ivan Stoev    7 年前

    Json.NET 允许您将其表示JSON内容的内部对象视为 dynamic

    唯一困难的问题是递归对象结构(即 nodes 数组),但这不是JSON或 具体问题,可以通过多种方式解决-明显的递归方法或使用我更喜欢的树展平枚举(the Expand 从我的答案到 How to flatten tree via LINQ? ).

    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
  •  2
  •   Simone Cifani    7 年前

        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": []
              }
            ]
          }
        ]
      }
    ]