我有一个任意的JSON文档(即没有预先知道的固定模式),我想递归地向下搜索文档中任何级别上与某个 predicate 匹配的所有节点,以便进行一些必要的修改。如何使用JsonNode
文档对象模型执行这样的递归搜索?
具体内容如下。
假设我有一些JSON,如下面这样,其中可能包含属性"password"
的一个或多个示例:
[
{
"column1": "val_column1",
"column2": "val_column2",
"sheet2": [
{
"sheet2col1": "val_sheet2column1",
"sheet3": [
{
"sheet3col1": "val_sheet3column1",
"password": "password to remove"
}
]
},
{
"sheet2col1": "val_sheet2column1",
"sheet3": [
{
"sheet3col1": "val_sheet3column1"
}
]
}
]
},
{
"column1": "val2_column1",
"column2": "val2_column2",
"password": "password to remove",
"sheet2": [
{
"sheet2col1": "val_sheet2column1",
"sheet3": [
{
"sheet3col2": "val_sheet3column2"
},
null,
null,
19191
],
"password": "password to remove"
},
{
"sheet2col1": "val_sheet2column1",
"sheet3": [
{
"sheet3col2": "val_sheet3column2"
}
]
}
]
}
]
我需要将其解析为JsonNode
层次结构,并删除所有“password”属性(无论它们出现在JSON层次结构中的何处)。使用Json.NET,我可以将其解析为JToken
并使用DescendantsAndSelf()
:
var root = JToken.Parse(json);
var propertyToRemove = "password";
if (root is JContainer c)
foreach (var obj in c.DescendantsAndSelf().OfType<JObject>().Where(o => o.ContainsKey(propertyToRemove)))
obj.Remove(propertyToRemove);
var newJson = root.ToString();
但是JsonNode
没有一个等价的方法,我如何使用System.Text.json来完成这个任务呢?
1条答案
按热度按时间vq8itlhq1#
由于
JsonNode
没有与DescendantsAndSelf()
等效的函数,因此我们必须自己创建一个:而现在我们将能够做到:
演示小提琴#1 here。
请记住与Json.NET的LINQ to JSON的以下区别:
1.为
null
JSON值返回的JsonNode
(例如{"value":null}
)实际上为空。LINQ to JSON将null
JSON值表示为非空JValue
,其中JValue.Type
等于JTokenType.Null
。JsonNode
没有任何等价于Json.NET的JProperty
的东西。对象中值的parent将是对象本身。因此,没有直接的方法通过JsonNode
文档对象模型来确定所选JsonNode
属性值的属性名。因此,如果你需要通过值(而不是名称)搜索和修改属性,你可以使用第二个扩展方法
DescendantItemsAndSelf()
,它包括父节点和名称或索引沿着当前节点。例如,要删除所有null
属性值,请执行以下操作:演示小提琴#2。