例如,我在C#中有一个像这样的json:
{
"Harry.firstName": "Harry",
"Harry.lastName": "Birimirski",
"Harry.recordTitle": "My title",
"Harry.SomeRepeatable": [{
"GUID": "9dd8c7bb-64e1-452b-90d5-db2b6e505492",
"NestedRepetable": [{
"GUID": "05aa2161-fcc2-45a6-b0b7-8749d94a2e61",
"nestedText": "Nested first"
},
{
"GUID": "dfd67eeb-703b-4cc4-9321-b6a39084e687",
"nestedText": "Nested first 2"
}
],
"name": "First"
},
{
"GUID": "3318e544-1be8-4795-9bab-fa05de79cf46",
"NestedRepetable": [{
"GUID": "c1b60869-7c75-4af4-8037-be26aeca7939",
"nestedText": "Nested second"
}],
"name": "Second"
}
]
}
我想按值从NestedRepetable
数组中删除项目。
例如,包含GUID的remove元素:05aa2161-fcc2-45a6-b0b7-8749d94a2e61
,所需的结果将类似于:
{
"Harry.firstName": "Harry",
"Harry.lastName": "Birimirski",
"Harry.recordTitle": "My title",
"Harry.SomeRepeatable": [{
"GUID": "9dd8c7bb-64e1-452b-90d5-db2b6e505492",
"NestedRepetable": [
{
"GUID": "dfd67eeb-703b-4cc4-9321-b6a39084e687",
"nestedText": "Nested first 2"
}
],
"name": "First"
},
{
"GUID": "3318e544-1be8-4795-9bab-fa05de79cf46",
"NestedRepetable": [{
"GUID": "c1b60869-7c75-4af4-8037-be26aeca7939",
"nestedText": "Nested second"
}],
"name": "Second"
}
]
}
我已经在Json.NET的帮助下尝试了几件事,但是我做不到。 请记住,整个JSON结构是动态的。我唯一知道的是这种情况下的字段名称(GUID)和应删除的字段中的值。
我已尝试按照本question中所述的方式进行操作, 但是他们使用的是json的硬编码路径。那不是我的情况。
我使用了以下代码:
private JToken RemoveFields(JToken token, string fieldValue)
{
JContainer container = token as JContainer;
if (container == null)
{
return token;
}
List<JToken> removeList = new List<JToken>();
foreach (JToken el in container.Children())
{
JProperty p = el as JProperty;
if (p != null)// && fields.Contains(p.Name))
{
if (p.Value.ToString() == fieldValue)
{
removeList.Add(el);
//try to remove the whole thing, not only GUID field ..
//removeList.Add(el.Parent);
}
}
RemoveFields(el, fieldValue);
}
foreach (JToken el in removeList)
{
el.Parent.Remove();
return token;
}
return token;
}
但是我收到以下错误:
集合已修改;枚举操作可能无法执行”
可能是因为我正在尝试删除父元素。
答案 0 :(得分:1)
您正在尝试查找和删除符合以下条件的对象:
"NestedRepetable"
的数组属性包含的所有对象"GUID"
且具有特定值的属性。最简单的方法是将JToken.SelectTokens()
与JSONPath query结合使用:
var value = "05aa2161-fcc2-45a6-b0b7-8749d94a2e61";
var queryStringTemplate = "..NestedRepetable[?(@.GUID == '{0}')]";
var query = root.SelectTokens(string.Format(queryStringTemplate, value));
foreach (var obj in query.ToList())
obj.Remove();
如果您实际上不关心对象是否嵌套在"NestedRepetable"
中(此时您的问题尚不清楚),您可以这样做
var queryStringTemplate = "..[?(@.GUID == '{0}')]";
注意:
..
是递归下降运算符。它会返回JToken
层次结构并返回所有值。
NestedRepetable
将具有所需名称的属性值匹配。
[?(@.GUID == '{0}')]
将属于NestedRepetable
数组的对象与具有指定值的名为GUID
的属性匹配。
在删除与查询匹配的令牌时,有必要通过调用ToList()
来实现查询,以避免出现Collection was modified
异常。
有关JSONPath语法的更多信息,请参见JSONPath - XPath for JSON。