如何根据 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
之前,您必须
- 反序列化为
Dictionary<string, object>
- 执行修改
- 将其序列化回 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 JsonElement
到 JsonNode
反之亦然:
var a3Node = JsonSerializer.Deserialize<JsonNode>(a3.Value);
a3Node = "a";
它并没有真正帮助,因为 a3Node
仅代表 a3
字段,根据我的理解,您不能只合并两个 JsonNode
。
我有一个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
之前,您必须
- 反序列化为
Dictionary<string, object>
- 执行修改
- 将其序列化回 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 JsonElement
到 JsonNode
反之亦然:
var a3Node = JsonSerializer.Deserialize<JsonNode>(a3.Value);
a3Node = "a";
它并没有真正帮助,因为 a3Node
仅代表 a3
字段,根据我的理解,您不能只合并两个 JsonNode
。