如何根据 System.Text.Json (.NET 6) 中的路径删除和更新?

How to delete and update based on a path in System.Text.Json (.NET 6)?

我有一个JSON文本:

{
   "a":[
      {
         "a1":"string",
         "a2":"string",
         "a3":"string"
      }
   ],
   "b":"2021-12-29T14:20:21.948Z",
   "c":{
      "c1":[
         {
            "c11":"string",
            "c12":"string",
            "c13":"string",
            "c14":true,
            "c15":true,
            "c16":"2021-12-29T14:20:21.948Z",
            "c17":"string"
         }
      ]
   }
}

JsonNode class总是有一个唯一的path我想用它们来找到特定的值(update/delete它们)。

所以,我想使用System.Text.Json.NET 6有以下方法:

public static JsonNode UpdateValue(string json /*JsonNode json*/, string path, object value)
{
    // ?
}

public static JsonNode RemovePath(string json /*JsonNode json*/, string path)
{
    // ?
}

可能吗?

更新 json 使用 Newtonsoft.Json

 string json = File.ReadAllText("json");
    dynamic jsonObj = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
    jsonObj["a"][0]["test1"] = "new values";
    string output = Newtonsoft.Json.JsonConvert.SerializeObject(jsonObj, Newtonsoft.Json.Formatting.Indented);

简而言之:很遗憾,您不能

修改

JsonDocument 在设计上是只读的。在介绍 JsonNode 之前,您必须

  1. 反序列化为Dictionary<string, object>
  2. 执行修改
  3. 将其序列化回 json

由于 .NET 6 中引入了 JsonNode,您可以执行以下操作

var node = JsonNode.Parse(json);
var rootObject = node as JsonObject;
var aArray = rootObject["a"] as JsonArray;
var firstA = aArray[0];
firstA["a3"] = "modified";

或者简而言之

var node = JsonNode.Parse(json);
node["a"][0]["a3"] = "modified";

按路径定位元素

尽管 need has been expressed in 2019 尚未解决。但正如layomia所说

This feature is proposed for .NET 6, but not committed. To be clear, we acknowledge that this is an important feature for many users, however, work on features with higher priority may prevent this from coming in .NET 6.

遗憾的是,此功能并未出现在 .NET 6 中。

有第 3 方库为 JsonDocument 提供此功能。最成熟的一种叫做JsonDocumentPath。使用它的 SelectElement 方法,您可以真正轻松地检索给定字段作为 JsonElement

var doc = JsonDocument.Parse(json);
JsonElement? a3 = doc.RootElement.SelectElement("$.a[0].a3");

互操作性

即使 there is a way to convert JsonElementJsonNode 反之亦然:

var a3Node = JsonSerializer.Deserialize<JsonNode>(a3.Value);
a3Node = "a";

它并没有真正帮助,因为 a3Node 仅代表 a3 字段,根据我的理解,您不能只合并两个 JsonNode