是否可以从JObject变量中删除字符串值的JSON节点? [英] Is it possible to remove string-valued JSON nodes from a JObject variable?

查看:95
本文介绍了是否可以从JObject变量中删除字符串值的JSON节点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用.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 named name anywhere in the JSON hierarchy. Assuming your JSON has a fairly fixed schema you might want to simplify that to select the name 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆