是否可以从JObject变量中删除字符串值的JSON节点? [英] Is it possible to remove string-valued JSON nodes from a JObject variable?
问题描述
我正在使用.NET 4.7,MVC5,C#和JSON.NET
I am using .NET 4.7, MVC5, C# and JSON.NET
我有一个名为"json"的JObject变量
I have a JObject variable called "json"
JObject jsonPerson = JObject.Parse(strPersonsDetails);
它包含名称相同但结构不同的节点:
It contains nodes with same name, but different structure:
name : "Joe Bloggs"
和
name : {
firstname : "Joe",
lastname : "Bloggs"
}
我想删除任何字符串类型的节点,即:
I would like to remove any node that are of type string ie :
name : "Joe Bloggs"
离开:
name : {
firstname : "Joe",
lastname : "Bloggs"
}
名称"类型的
是否可以从jsonPerson
中删除所有具有文本值的属性,而不是具有"name"类型的复杂类型的其他版本?
Is there any way to remove all properties called "name" which have a text value as opposed to the other version that has a complex type of type "name" from jsonPerson
?
更完整的JSON:
{
"items": [
{
"id" : 1,
"name" : "Joe Bloggs"
},
{
"id" : 2,
"name" : {
"FirstName" : "Joe",
"LastName" : "Bloggs"
}
}
]
}
推荐答案
您可以结合使用 JSONPath 查询以选择JSON层次结构中所有相关的"name"
节点的值,然后过滤那些 JTokenType.String
一个>.然后,您可以从父级JObject
中将它们移除包含JProperty
.
You can combine a JSONPath query to select the values of all relevant "name"
nodes in your JSON hierarchy, then filter those for which JToken.Type
is JTokenType.String
. Then you can remove them from their parent JObject
by removing the containing JProperty
.
以下代码可以完成这项工作:
The following code does the job:
// 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
的 all 属性的值.假设您的JSON具有相当固定的架构,则可能需要简化以选择name
节点在层次结构中的预期位置:
I used the JSONPath recursive descent operator
..
to select the values of all properties namedname
anywhere in the JSON hierarchy. Assuming your JSON has a fairly fixed schema you might want to simplify that to select thename
nodes at their expected location in the hierarchy:
var query = jsonPerson
.SelectTokens("items[*].name")
.Where(t => t.Type == JTokenType.String);
其中*
是通配符运算符,用于选择所有数组条目.演示小提琴#2 此处.
Where *
is the wildcard operator selecting all array entries. Demo fiddle #2 here.
SelectTokens
返回所选属性值.为了从层次结构中删除这些值,必须删除包含的JProperty
.扩展方法JsonExtensions.RemoveFromLowestPossibleParent()
可以做到这一点.
SelectTokens
returns the selected property values. In order to remove those values from the hierarchy it is necessary to remove the containing JProperty
. The extension method JsonExtensions.RemoveFromLowestPossibleParent()
does this.
这篇关于是否可以从JObject变量中删除字符串值的JSON节点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!