JToken, JObject, JArray 的一些内容

85 篇文章 0 订阅

最近的task在处理json相关的内容

简单描述:

解析json数据的一般方式: 用反序列化来实现json数据的解读,这需要首先知道json数据的结构并且建立相应的类才能反序列化

问题:一旦遇到动态的json数据,这种方法就不使用

解决方案:Newtonsoft.Json封装类,里面的JToken直接实现对JSON的增删改查。

JToken的层次结构是这样的:

JToken         -抽象基类
  JContainer     - 能够包含其它JToken的JToken抽象基类
    JArray     - 表示一个JSON数组(包含一个有序的List)
    JObeject    - 表示一个JSON对象(包含一个IEnumerable)
    JProperty   - 表示一个JSON属性(在JObject中是一个name/JToken键值对)
  JValue       - 表示一个原生JSON值(string,number,boolean,null)

增删改查的例子:

var cardJson = "['身份证','银行卡','门禁卡']";
            var cardJArray = JArray.Parse(cardJson);
            var p = new Person { Name="fan",Age=12,Dog=new Dog { Name="奶牛"} };
        JObject jobj= JObject.FromObject(p);
//添加属性
            jobj["NickName"] = "fan";
            jobj["Wifes"] = new JArray("rose", "lisa");
            ((JArray)jobj["Wifes"]).Add( "july");
            jobj["Cards"] = cardJArray;
            //修改属性
            jobj["Name"] = "li";
            jobj["Age"] = 9;
            jobj["Dog"]["Name"] = "阿黄";
            ((JArray)jobj["Wifes"])[0] = "roses";
            //插入属性
            jobj.Property("Name").AddBeforeSelf(new JProperty("ID", 1));
            //删除属性
            jobj.Property("Age").Remove();
            ((JArray)jobj["Wifes"])[2].Remove();
            //查找
            //遍历属性
            var props = jobj.Children().Values();
            foreach (var prop in props)
            {
                if (!(prop is JObject) && !(prop is JArray))
                {
                    Console.WriteLine(prop.ToString());
                }               
            }
            //遍历数组
            var cardList = ((JArray)jobj["Cards"]);
            foreach (var card in cardList)
            {
                Console.WriteLine(card.ToString());
            }
            //强类型读取
            Console.WriteLine(jobj.Value<int>("ID")); 
            var p2 = jobj.ToString();

使用集合初始化语法:

JObject o = new JObject 
            {
                {"CPU","Intel"},
                {"Memory",2048},
                {
                    "Drives",new JArray
                    {
                        "DVD",
                        "U盘"
                    }
                }
            };
 
            Console.WriteLine(o.ToString());

使用JTokenWriter初始化

JTokenWriter writer = new JTokenWriter();
            writer.WriteStartObject();
            writer.WritePropertyName("Title");
            writer.WriteValue("aaaaaaa???");
 
            writer.WritePropertyName("Detail");   
        
            writer.WriteStartArray();
            writer.WriteValue("Yes");
            writer.WriteValue("No");
            writer.WriteValue("Unknown");
            writer.WriteEndArray();
 
            writer.WriteEndObject();
 
            JObject o = (JObject)writer.Token;
            Console.WriteLine(o.ToString());

使用.NET值初始化:

JValue i = (JValue)JToken.FromObject(123);
            Console.WriteLine(i.Type);
            Console.WriteLine(i.ToString());
 
            JValue s = (JValue)JToken.FromObject("GongHui");
            Console.WriteLine(s.Type);
            Console.WriteLine(s.ToString());
 
            Address address = new Address
            {
                City = "GuangZhou",
                Province = "GuangDong",
                County = "ShiQiao",
                Villages = new List<string>
                {
                    "111",
                    "222"
                }
            };
 
            JObject o = (JObject)JToken.FromObject(address);
            Console.WriteLine(o.ToString());

遍历JSON属性(重要):

/// <summary>
/// 遍历所有节点,替换其中某个节点的值
/// </summary>
/// <param name="jobj">json数据</param>
/// <param name="nodeName">节点名</param>
/// <param name="value">新值</param>
private static void JSON_SetChildNodes(ref JToken jobj, string nodeName, string value)
{
    try
    {
        JToken result = jobj as JToken;//转换为JToken
        JToken result2 = result.DeepClone();
        //复制一个返回值,由于遍历的时候JToken的修改会终止遍历,因此需要复制一个新的返回json
        //遍历
        var reader = result.CreateReader();
        while (reader.Read())
        {
            if (reader.Value != null)
            {
                if (reader.TokenType == JsonToken.String || reader.TokenType == JsonToken.Integer || reader.TokenType == JsonToken.Float)
                {
                    Regex reg = new Regex(@"" + nodeName + "$");
                    //SelectToken(Path)方法可查找某路径下的节点,
                    //在Newtonsoft.Json 4.5 版本中不可使用正则匹配,
                    //在6.0版本中可用使用,会方便很多,6.0版本下替换值会更方便,
                    //这个需要特别注意的
                    if (reg.IsMatch(reader.Path))
                    {
                        result2.SelectToken(reader.Path).Replace(value);
                    }
                }
            }
        }
        jobj = result2;
    }
    catch (Exception ex)
    {
    }
}

手动创建JObject:

var json = new JObject(
        new JProperty("status", result.Status.ToString()),
        new JProperty("results", new JObject(result.Entries.Select(pair =>
            new JProperty(pair.Key, new JObject(
                new JProperty("status", pair.Value.Status.ToString()),
                new JProperty("description", pair.Value.Description),
                new JProperty("data", new JObject(pair.Value.Data.Select(
                    p => new JProperty(p.Key, p.Value))))))))));


var str = json.ToString();

有用的相关操作

JToken合并:

需要引一个Nuget包:MassTransit

添加引用:using MassTransit.Courier.Serialization;

jObj.Merge(JObject.Parse(userTranslate.ValueJSON));

 JToken查找:

jObject.SelectToken($".{path}");//根据路径查找

 Object转JToken:

JToken.FromObject(object)

 JToken转Object:

jObj.ToObject<List<ApiOrderInfoSelectModel>>();

Merge方法:合并json

     JObject o1 = JObject.Parse(@"{
              'FirstName': 'John',
              'LastName': 'Smith',
              'Enabled': false,
              'Roles': [ 'User' ]
            }");
            JObject o2 = JObject.Parse(@"{
              'Enabled': true,
              'Roles': [  'Admin' ]
            }");

            o1.Merge(o2, new JsonMergeSettings
            {
                // union arrays together to avoid duplicates
                MergeArrayHandling = MergeArrayHandling.Union
            });

            string json = o1.ToString();
            // {
            //   "FirstName": "John",
            //   "LastName": "Smith",
            //   "Enabled": true,
            //   "Roles": [
            //     "User",
            //     "Admin"
            //   ]
            // }

Reference:

1.  https://www.cnblogs.com/fanfan-90/p/12659937.html

06-02
如果你有一个包含多个FTreeEntity对象的json数组,你可以使用JArray对象来代替JObject对象,然后在foreach循环中替换每个FTreeEntity对象中的FNumber值。下面是一个示例代码,可以帮助你实现这个功能: ```csharp using Newtonsoft.Json.Linq; // 假设你有一个包含多个FTreeEntity对象的json数组 string jsonString = "[{\"FTreeEntity\":[{\"FCHILDUNITID\":{\"FNumber\":\"\"},\"FEntrySource\":\"1\",\"FDOSAGETYPE\":\"2\",\"FISSUETYPE\":\"1\",\"FOverControlMode\":\"\",\"FMATERIALIDCHILD\":{\"FNumber\":\"\"}}]}]"; // 转换为 JArray 对象 JArray jsonArray = JArray.Parse(jsonString); // 定义要替换的 key 和新的 value string keyToReplace = "FNumber"; string newValue = "new value"; // 遍历每个 FTreeEntity 对象 foreach (JToken token in jsonArray) { JToken fTreeEntity = token["FTreeEntity"]; if (fTreeEntity != null) { // 遍历 FTreeEntity 对象中的每个 JToken foreach (JToken childToken in fTreeEntity.Descendants()) { if (childToken is JProperty property && property.Name == keyToReplace) { // 替换 JToken 的值 property.Value = newValue; } } } } // 转换回 json 字符串 string newJsonString = jsonArray.ToString(); ``` 在上面的代码中,我们首先使用 JArray.Parse 方法将 json 字符串转换为 JArray 对象,然后遍历每个 FTreeEntity 对象,并使用 JToken.Descendants 方法查找该对象中的所有子节点。如果子节点是 JProperty 对象,并且它的名称是 keyToReplace,我们就使用 property.Value 属性替换子节点的值。最后,我们将替换后的 JArray 对象转换为新的 json 字符串。 请注意,JToken.Descendants 方法会遍历所有子节点,包括对象、数组、属性等。如果你只想遍历特定类型的节点,可以使用 JContainer.DescendantsAndSelf 方法,并提供要筛选的节点类型作为参数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

董厂长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值