c#: Newtonsoft.Json 高级用法二(jsonpath)
环境:
- .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)相关推荐
- Newtonsoft.Json高级用法
手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口多次修改中,实体添加了很多字段用于中间计算或者存储,然后最终用Newtonsoft.Json进行序列化返回数 ...
- [转]Newtonsoft.Json高级用法
本文转自:http://www.cnblogs.com/yanweidie/p/4605212.html 手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口多 ...
- C# Newtonsoft.Json 高级用法
Newtonsoft.Json介绍: 做Web开发的,没有接触过JavaScript的肯定很少,做前端开发,没有接触过Ajax的估计更不多了.现在的系统大多数是分布式系统,分布式系统就会涉及到数据的传 ...
- c#: Newtonsoft.Json 高级用法一(不创建类,动态解析和构造json、JObject/JArray)
环境: .net core3.1 vs2019 Newtonsoft.Json 12.0.3 关于newtonsoft.json的使用常见问题参考: <c#:序列化json常见问题及处理方法&g ...
- Newtonsoft.Json日常用法
原文链接:https://www.cnblogs.com/ZengJiaLin/p/9578794.html
- Newtonsoft.Json反序列化(Deserialize)出错:Bad JSON escape sequence
使用Newtonsoft.Json反序列化收到的字串为JObject或其它支持的数据模型,有时错误,提示如下: Bad JSON escape sequence: \c. Path 'idno', l ...
- TileMap高级用法
近段时间主要是在研究开发工具与游戏制作的结合,大家知道工欲善其事必先利其器,一款好的方便的开发工具能够极大的提高游戏的开发效率,特别是在制作关卡这些东西的时候,这也就是为什么国外现在有这么多的开发引擎 ...
- [C#][Newtonsoft.Json] Newtonsoft.Json 序列化时的一些其它用法
Newtonsoft.Json 序列化时的一些其它用法 在进行序列化时我们一般会选择使用匿名类型 new { },或者添加一个新类(包含想输出的所有字段).但不可避免的会出现以下情形:如属性值隐藏(敏 ...
- Newtonsoft.Json(Json.net)的基本用法
Newtonsoft.Json(Json.net)的基本用法 添加引用: 使用NuGet,命令:install-package Newtonsoft.Json 实体类: public class Bo ...
- SpringBatch 写文件JSON(JsonFileItemWriter)用法(十二)
文章目录 一.抽取写出json文件公共writer 二.processor 三.配置写json文件job 四.执行job 前言:在一些业务场景中,可能需要写出json,来做业务逻辑处理,SpringB ...
最新文章
- 解决sdk manager 下载API失败的问题
- 网站推广方法众多,对此你了解多少?
- The Way to TiDB 3.0 and Beyond (下篇)
- 字符串得结果!Java数组模拟栈以实现中缀表达式综合计算器,字符串表达式计算器
- 图解 RoIAlign 以及在 PyTorch 中的使用(含代码示例)
- js function随笔
- html菜单不动属性,html5规定元素的上下文菜单属性contextmenu
- asp.net获取ip地址的方法
- .net 移动端 web 上传图片_vue使用cropperjs实现移动端图片裁剪上传组件
- AutoItLibrary
- 文字布局(TEXT STYLE)标记(TAGS)
- Windows Server 2016 路由和远程访问
- 3600000毫秒等于多少小时,一小时等于多少毫秒
- iOS 5.1实现旋转屏幕
- c语言杖举,形近字组词。直()植()杖()仗()提()题()漫()慢()
- 此文件中的某些Unicode字符未能保存在当前代码页中
- 磁波刀和海扶刀的区别
- C语言_公倍数、最小公倍数_调用函数求最大公因数最小公倍数
- 在 Java 中如何加快大型集合的处理速度
- Java之二维码工具包-yellowcong
热门文章
- STM32固件库包的下载与安装
- texlive写论文源代码_基于中国人民大学LaTeX论文模板毕业论文,课程研究生硕士本科设计,ppt答辩,外文翻译程序源代码下载...
- 注册测绘师 案例分析
- 当前GitHub上排名前十的热门Vue项目
- java keytool用法,java中Keytool的使用总结
- java keytool 工具
- Moodle 3.7安装
- 三菱PLC-GXWorks2程序下载
- 数据结构(C语言版第二版)思维导图
- matlab利用数值 积分的方法求,MATLAB求数值积分的方法