C# 是否可以从JObject变量中删除字符串值的JSON节点?
我使用的是.NET4.7、MVC5、C和JSON.NET 我有一个名为json的JObject变量C# 是否可以从JObject变量中删除字符串值的JSON节点?,c#,asp.net-mvc-5,json.net,C#,Asp.net Mvc 5,Json.net,我使用的是.NET4.7、MVC5、C和JSON.NET 我有一个名为json的JObject变量 JObject jsonPerson = JObject.Parse(strPersonsDetails); 它包含名称相同但结构不同的节点: name : "Joe Bloggs" 及 我想删除任何类型为字符串ie的节点: name : "Joe Bloggs" 然后离开: name : { firstname : "Joe", lastname : "Bl
JObject jsonPerson = JObject.Parse(strPersonsDetails);
它包含名称相同但结构不同的节点:
name : "Joe Bloggs"
及
我想删除任何类型为字符串ie的节点:
name : "Joe Bloggs"
然后离开:
name : {
firstname : "Joe",
lastname : "Bloggs"
}
类型为name
是否有任何方法可以从jsonPerson中删除所有名为name的属性,这些属性具有文本值,而不是具有复杂类型name的其他版本
编辑:
更完整的JSON:
{
"items": [
{
"id" : 1,
"name" : "Joe Bloggs"
},
{
"id" : 2,
"name" : {
"FirstName" : "Joe",
"LastName" : "Bloggs"
}
}
]
}
您可以组合一个查询来选择JSON层次结构中所有相关名称节点的值,然后过滤这些值。然后,通过删除包含的JProperty,可以从其父JObject中删除它们
以下代码执行此任务:
// Select the values of all relevant "name" nodes using a JSONPath query,
// https://goessner.net/articles/JsonPath/
// Then select only those whose which are of type string.
var query = jsonPerson
.SelectTokens("..name")
.Where(t => t.Type == JTokenType.String);
query.ToList().ForEach(t => t.RemoveFromLowestPossibleParent());
使用扩展方法:
public static partial class JsonExtensions
{
public static JToken RemoveFromLowestPossibleParent(this JToken node)
{
if (node == null)
return null;
// If the parent is a JProperty, remove that instead of the token itself.
var contained = node.Parent is JProperty ? node.Parent : node;
contained.Remove();
// Also detach the node from its immediate containing property -- Remove() does not do this even though it seems like it should
if (contained is JProperty)
((JProperty)node.Parent).Value = null;
return node;
}
}
演示小提琴
注:
我使用了JSONPath递归下降运算符。。选择JSON层次结构中任意位置名为name的所有属性的值。假设您的JSON有一个相当固定的模式,您可能希望简化该模式,以便在层次结构中的预期位置选择名称节点:
var query = jsonPerson
.SelectTokens("items[*].name")
.Where(t => t.Type == JTokenType.String);
其中*是选择所有数组项的通配符运算符。演示小提琴2
返回选定的属性值。要从层次结构中删除这些值,必须删除包含的JProperty。扩展方法JsonExtensions.RemoveFromLowestPossibleParent执行此操作
我想删除所有名为name的属性,这些属性有一个文本值,而另一个版本有一个复杂的name类型。我添加了一个更完整的示例,如果这会以任何方式影响您的答案。感谢您的全面回复,事实上是令人惊讶的回复更具体地说,我是否可以更改SelectTokensitems.name的路径?否,因为items的值是数组。您需要使用items[*].name来选择所有数组值。演示小提琴2:
var query = jsonPerson
.SelectTokens("items[*].name")
.Where(t => t.Type == JTokenType.String);