如何在C#中的嵌套json结构中删除键值对

时间:2020-10-20 12:31:43

标签: c# json json.net

我有以下json

{       
 "audit_date": "2020-05-13T11:27:10.3187798Z",
 "client_uuid": "2fd77dd8-ed76-4bba-b0e1-5cda454c8d6e",
 "audit_entry": {
    "where_uri": "test.com/dataservice/apps/171f0841-825b-4964-8f8c-0869650f14a6",
    "why_uri": "test.com/dataservice/reference/reasons_for_change/61acc173-7168-4ae5-9f04- afa228941f8b",
    "who_uri": "test.com/securityservice/users/4977dae1-a307-425f-980c-53413fef1b0f",
    "when_audited": "2018-11-13T20:20:39+00:00",
    "what_uri": "test.com/dataservice/study_subjects/1bc67a71-8549-4ab8-9dd9-e44238198860",
    "what_changed": [
        {
            "attribute_name": "birth_year",
            "attribute_value": "1969",
        "attribute_change": "1970"
        },
        {
            "attribute_name": "subject_reference",
            "attribute_value": "TEST-WOO3444",
            "attribute_change": null
        }
      ]
     }
    }

我想删除第二个attribute_change键值对,如下所示

{       
"audit_date": "2020-05-13T11:27:10.3187798Z",
"client_uuid": "2fd77dd8-ed76-4bba-b0e1-5cda454c8d6e",
"audit_entry": {
    "where_uri": "test.com/dataservice/apps/171f0841-825b-4964-8f8c-0869650f14a6",
    "why_uri": "test.com/dataservice/reference/reasons_for_change/61acc173-7168-4ae5-9f04- afa228941f8b",
    "who_uri": "test.com/securityservice/users/4977dae1-a307-425f-980c-53413fef1b0f",
    "when_audited": "2018-11-13T20:20:39+00:00",
    "what_uri": "test.com/dataservice/study_subjects/1bc67a71-8549-4ab8-9dd9-e44238198860",
    "what_changed": [
        {
            "attribute_name": "birth_year",
            "attribute_value": "1969",
        "attribute_change": "1970"
        },
        {
            "attribute_name": "subject_reference",
            "attribute_value": "TEST-WOO3444",
            
        }
      ]
     }
    }

我尝试了以下代码

        JObject jObject = JObject.Parse(jsonText);
        JObject jObj = (JObject)jObject.SelectToken("audit_entry");

        //remove second attribute changed token
        jObj.Property("what_changed")("attribute_change")[1].Remove();

        string json = jObj.ToString(Formatting.None);

我知道jObj.Property的语法错误,但是经过几个小时的搜寻后,我找不到答案。 任何帮助表示赞赏。

3 个答案:

答案 0 :(得分:1)

搜索开始的属性名称及其结尾。然后将json字符串之前/之后连接成一个新字符串。也许是骇客,但它会使您保持编码状态,直到找到更优雅的解决方案为止。

答案 1 :(得分:1)

您可以通过调用具有相应属性名称的JObject方法来从Remove中删除属性。例如:

JObject jObject = JObject.Parse(jsonText);

// find required object, there are other options
// for example (JObject)jObject["audit_entry"]["what_changed"][1]
var nested = (JObject)jObject.SelectToken("$.audit_entry.what_changed[1]"); 

//remove attribute changed token
nested.Remove("attribute_change");
string json = jObject.ToString(Formatting.None); // attribute_change is removed from jObject

如果要删除所有具有此类名称和null作为值的属性,则可以执行下一步:

        var toRemove = jObject.Descendants()
            .OfType<JProperty>()
            .Where(prop => prop.Name == "attribute_change" && prop.Value.Type == JTokenType.Null)
            .ToList();
        foreach (var prop in toRemove)
        {
            prop.Remove();
        }

答案 2 :(得分:1)

由于what_changed是一个数组,因此您应强制转换为JArray才能访问其元素并删除attribute_change令牌

var jObject = JObject.Parse(jsonText);

if (jObject["audit_entry"]?["what_changed"] is JArray array)
    if (array[1] is JObject attribute)
        attribute.Remove("attribute_change");

Console.WriteLine(jObject);