环境:

  • .net6.0
  • vs2022
  • Newtonsoft.Json 12.0.3

关于newtonsoft.json的使用常见问题参考:
《c#:序列化json常见问题及处理方法》
《c#:关于NewtonsoftJson序列化和Grpc序列化的冲突问题》
《c#: Newtonsoft.Json 高级用法》

问题:如何从json中快速提取数据?

比如有下面的json:

[{"name":"小明","books":[{"name":"明-语文","year":5}]},{"name":"Tom","books":[{"name":"Tom-物理","year":3}]}
]
  • 问题1: 如何提取所有的书籍名字呢?
  • 问题2: 如歌提取year在3年以上的书籍名字?

解决办法:使用jsonPath

直接上代码:

 //使用c#11语法,当前需要将工程设置预览,即在.csproj的根目录下加入:/*<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"><LangVersion>preview</LangVersion>
</PropertyGroup><PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'"><LangVersion>preview</LangVersion>
</PropertyGroup>*/var str = """[{"name":"小明","books":[{"name":"明-语文","year":5}]},{"name":"Tom","books":[{"name":"Tom-物理","year":3}]}]""";var root = Newtonsoft.Json.JsonConvert.DeserializeObject<JArray>(str);//提取所有的书籍名字呢Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(root.SelectTokens("$[*].books[*].name")));//输出: ["明-语文","Tom-物理"]//提取year在3年以上的书籍名字Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(root.SelectTokens("$[*].books[?(@.year>3)].name")));//输出: ["明-语文"]

jsonPath 语法细节

参考:
《Newtonsoft.Json文档: Querying JSON with JSON Path》
《JSONPath规则》

首先,我们需要明确:
在 newtonsoft 中我们可以将对象粗略的表示为下面两种类型:

  • 数组: 用JArray表示;
  • 非数组(对象或值):用JObject表示;

它们都继承自:JToken

然后,我们看newtonsoft提供jsonpath的方法:

  • public IEnumerable<JToken> SelectTokens(string path):

    期待返回的是数组,所以:无论是否找到或找到几个都会返回一个数组

  • public JToken? SelectToken(string path):

    期待返回的是非数组,所以:没找到返回null,找到1个就返回JToken,找到多个就报错!!!

有了上面的前提,我们来看jsonpath的语法介绍:

下面用一个实例介绍:

private static void TestBase()
{var str = """[{"name":"小明","age":20,"books":[{"name":"明-语文","year":5,"must":true},{"name":"明-数学","year":2,"must":false}]},{"name":"小红","age":18,"birth":"1998-01-01","books":[{"name":"红-政治","year":6,"must":false},{"name":"红-体育","year":4,"must":false}]},{"name":"Tom","age":22,"birth":null,"books":[{"name":"Tom-物理","year":6,"must":"true"}]}]
""";var root = str.ToObject<JArray>();//输出原样Console.WriteLine(root.SelectToken("$").ToJson());//output: 省略//打印null,因为$是一个数组,它不是对象,没有name属性Console.WriteLine(root.SelectToken($"$.name").ToJson());//output: null//打印所有的name,包括人的姓名和书籍名称Console.WriteLine(root.SelectTokens($"$..name").ToJson());//output: ["小明","明-语文","明-数学","小红","红-政治","红-体育","Tom","Tom-物理"]//打印所有书籍的名称Console.WriteLine(root.SelectTokens($"$..books..name").ToJson());//output: ["明-语文","明-数学","红-政治","红-体育","Tom-物理"]//打印年龄小于20的人所有书籍名称Console.WriteLine(root.SelectTokens($"$[?(@.age < 20)].books..name").ToJson());//output: ["红-政治","红-体育"]//打印小明的所有书籍名称Console.WriteLine(root.SelectTokens($"$[?(@.name == '小明')].books..name").ToJson());//output: ["明-语文","明-数学"]//打印有birth属性的所有书籍名称Console.WriteLine(root.SelectTokens($"$[?(@.birth)].books..name").ToJson());//output: ["红-政治","红-体育","Tom-物理"]//打印有birth属性并且age>20的人的所有书籍名称Console.WriteLine(root.SelectTokens($"$[?(@.birth && @.age>20)].books..name").ToJson());//output: ["Tom-物理"]//打印有birth属性并且birth不为空的人的所有书籍名称Console.WriteLine(root.SelectTokens($"$[?(@.birth && @.birth != '' && @.birth <>null)].books..name").ToJson());//output: ["红-政治","红-体育"]//正则: 打印所有姓名"小"开头人的所有书籍名称Console.WriteLine(root.SelectTokens($"$[?(@.name =~ /^小.+$/)].books..name").ToJson());//output: ["明-语文","明-数学","红-政治","红-体育"]//打印拥有必读书籍的人的所有书籍名称: 注意 must 是完全相等,字符串 "true" 不行Console.WriteLine(root.SelectTokens($"$[?(@.books[?(@.must===true)])].books..name").ToJson());//output: ["明-语文","明-数学"]//打印所有人的所有书籍: 注意 是二维数组结构Console.WriteLine(root.SelectTokens($"$..books").ToJson());//output: 省略//打印所有人的所有书籍: 注意 是一维结构Console.WriteLine(root.SelectTokens($"$..books[*]").ToJson());//output: 省略//打印所有书籍名称Console.WriteLine(root.SelectTokens($"$..books[*].name").ToJson());//output: ["明-语文","明-数学","红-政治","红-体育","Tom-物理"]//数组切片 [start: end:step]//打印最后一个人的最后一个书籍信息Console.WriteLine(root.SelectTokens($"$[-1:].books[-1:]").ToJson());//output: [{"name":"Tom-物理","year":6,"must":"true"}]//打印前两个人的最后一个书籍信息Console.WriteLine(root.SelectTokens($"$[0,1].books[-1:]").ToJson());//output: [{"name":"明-数学","year":2,"must":false},{"name":"红-体育","year":4,"must":false}]//打印第一个、第三个人的最后一个书籍信息(起始0,结束3,步长2,正好跳过中间的小红)Console.WriteLine(root.SelectTokens($"$[0:3:2].books[-1:]").ToJson());//output: [{"name":"明-数学","year":2,"must":false},{"name":"Tom-物理","year":6,"must":"true"}]//打印第一个人的最后一个书籍信息(从第一个到倒数第二个,不包含倒数第二个,所以就只能是第一个人(总共3个))Console.WriteLine(root.SelectTokens($"$[0:-2].books[-1:]").ToJson());//output: [{"name":"明-数学","year":2,"must":false}]
}//扩展方法: ToJson ToObject
public static class JsonExtensions
{public static string ToJson(this object obj){return JsonConvert.SerializeObject(obj);}public static T ToObject<T>(this string str){return JsonConvert.DeserializeObject<T>(str);}
}

其中的切片语法:

参考:《Python-序列切片原理和切片协议-[start

c#: Newtonsoft.Json 高级用法二(jsonpath)相关推荐

  1. Newtonsoft.Json高级用法

    手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口多次修改中,实体添加了很多字段用于中间计算或者存储,然后最终用Newtonsoft.Json进行序列化返回数 ...

  2. [转]Newtonsoft.Json高级用法

    本文转自:http://www.cnblogs.com/yanweidie/p/4605212.html 手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口多 ...

  3. C# Newtonsoft.Json 高级用法

    Newtonsoft.Json介绍: 做Web开发的,没有接触过JavaScript的肯定很少,做前端开发,没有接触过Ajax的估计更不多了.现在的系统大多数是分布式系统,分布式系统就会涉及到数据的传 ...

  4. c#: Newtonsoft.Json 高级用法一(不创建类,动态解析和构造json、JObject/JArray)

    环境: .net core3.1 vs2019 Newtonsoft.Json 12.0.3 关于newtonsoft.json的使用常见问题参考: <c#:序列化json常见问题及处理方法&g ...

  5. Newtonsoft.Json日常用法

    原文链接:https://www.cnblogs.com/ZengJiaLin/p/9578794.html

  6. Newtonsoft.Json反序列化(Deserialize)出错:Bad JSON escape sequence

    使用Newtonsoft.Json反序列化收到的字串为JObject或其它支持的数据模型,有时错误,提示如下: Bad JSON escape sequence: \c. Path 'idno', l ...

  7. TileMap高级用法

    近段时间主要是在研究开发工具与游戏制作的结合,大家知道工欲善其事必先利其器,一款好的方便的开发工具能够极大的提高游戏的开发效率,特别是在制作关卡这些东西的时候,这也就是为什么国外现在有这么多的开发引擎 ...

  8. [C#][Newtonsoft.Json] Newtonsoft.Json 序列化时的一些其它用法

    Newtonsoft.Json 序列化时的一些其它用法 在进行序列化时我们一般会选择使用匿名类型 new { },或者添加一个新类(包含想输出的所有字段).但不可避免的会出现以下情形:如属性值隐藏(敏 ...

  9. Newtonsoft.Json(Json.net)的基本用法

    Newtonsoft.Json(Json.net)的基本用法 添加引用: 使用NuGet,命令:install-package Newtonsoft.Json 实体类: public class Bo ...

  10. SpringBatch 写文件JSON(JsonFileItemWriter)用法(十二)

    文章目录 一.抽取写出json文件公共writer 二.processor 三.配置写json文件job 四.执行job 前言:在一些业务场景中,可能需要写出json,来做业务逻辑处理,SpringB ...

最新文章

  1. 解决sdk manager 下载API失败的问题
  2. 网站推广方法众多,对此你了解多少?
  3. The Way to TiDB 3.0 and Beyond (下篇)
  4. 字符串得结果!Java数组模拟栈以实现中缀表达式综合计算器,字符串表达式计算器
  5. 图解 RoIAlign 以及在 PyTorch 中的使用(含代码示例)
  6. js function随笔
  7. html菜单不动属性,html5规定元素的上下文菜单属性contextmenu
  8. asp.net获取ip地址的方法
  9. .net 移动端 web 上传图片_vue使用cropperjs实现移动端图片裁剪上传组件
  10. AutoItLibrary
  11. 文字布局(TEXT STYLE)标记(TAGS)
  12. Windows Server 2016 路由和远程访问
  13. 3600000毫秒等于多少小时,一小时等于多少毫秒
  14. iOS 5.1实现旋转屏幕
  15. c语言杖举,形近字组词。直()植()杖()仗()提()题()漫()慢()
  16. 此文件中的某些Unicode字符未能保存在当前代码页中
  17. 磁波刀和海扶刀的区别
  18. C语言_公倍数、最小公倍数_调用函数求最大公因数最小公倍数
  19. 在 Java 中如何加快大型集合的处理速度
  20. Java之二维码工具包-yellowcong

热门文章

  1. STM32固件库包的下载与安装
  2. texlive写论文源代码_基于中国人民大学LaTeX论文模板毕业论文,课程研究生硕士本科设计,ppt答辩,外文翻译程序源代码下载...
  3. 注册测绘师 案例分析
  4. 当前GitHub上排名前十的热门Vue项目
  5. java keytool用法,java中Keytool的使用总结
  6. java keytool 工具
  7. Moodle 3.7安装
  8. 三菱PLC-GXWorks2程序下载
  9. 数据结构(C语言版第二版)思维导图
  10. matlab利用数值 积分的方法求,MATLAB求数值积分的方法