JSONPath是什么?JSON数据查询语法与实战示例详解

liuzw 14 0

做后端调接口拿回一大坨嵌套JSON,想取某个深处的值,写代码一层层判空取属性,啰嗦还容易空指针。其实有个东西叫JSONPath,写一行表达式就能定位任意节点,跟XPath对XML、正则对文本一个意思。搞懂语法,处理复杂JSON效率高得多。

JSONPath是什么

JSONPath是一种查询语言,专门针对JSON数据结构,用表达式描述怎么从根节点走到目标节点。它最早由Stefan Goessner提出,后来被各种语言实现,比如Java的Jayway、Python的jsonpath-ng、JS的jsonpath-plus。虽然各实现细节有差异,但核心语法一致。

它的价值在于,不用写一堆if判断和循环,一行表达式就能从深层嵌套里捞出想要的值或一批值,特别适合处理API返回的复杂结构、做数据提取和断言。

基础语法:访问节点

美元符号代表根对象。点号或方括号访问子节点,两种写法等价。比如对象store的book属性,写美元点store点book,或者美元方括号store方括号book。book是个数组,取第一个用方括号零,写作美元点store点book方括号零。再取它的title,写美元点store点book方括号零点title。

数组的元素用方括号加索引访问,索引从零开始。负索引表示从后往前,方括号负一取最后一个,负二倒数第二个。这点和很多语言一致。

通配符和切片

星号是通配符,匹配当前层所有元素。比如美元点store点book点星号,取出book数组里每本书的所有属性值拼成列表。星号在数组上取所有元素,在对象上取所有属性值。

方括号里写start比end是切片,和Python切片类似但语义略不同。比如book方括号零比二,取第零到第一个元素。具体是否包含右端看实现,Jayway包含左不包含右。切片能快速取一段,不用循环。

方括号里还能写多个索引逗号分隔,比如book方括号零逗号二,取第零和第二个元素,跳过第一个。适合非连续取值。

递归下降:最有用的那个

两个点号点点是递归下降,意思是不管嵌套多深,把所有匹配的节点都捞出来。比如美元点点点book,从根开始不管在哪一层,所有叫book的节点全取出来。这是JSONPath最强大的地方,处理未知深度的结构时一行搞定。

常见用法是美元点点点点名,在整个JSON里找所有这个名字的字段。比如美元点点点id,把任意层的id全捞出来。调试未知结构时特别好用,不用先摸清结构再取值。

过滤表达式

方括号问号加圆括号是过滤,用at符号代表当前节点,写条件表达式。比如美元点store点book方括号问号圆括号at点price小于十圆括号,筛选book数组里price小于十的所有书。at代表当前遍历到的那个元素,能访问它的属性做比较。

过滤里支持比较运算、逻辑与或非、正则匹配等,看实现。Jayway支持等于、不等于、大于小于、正则等于波浪线。比如book方括号问号at点category等于等于字符串fiction圆括号,筛出category为fiction的书。过滤是JSONPath真正强大的查询能力,不只能定位还能筛选。

实战示例

假设一个 bookstore 的JSON,store下有book数组和bicycle对象。取所有书的标题:美元点store点book方括号星号点title。取所有价格:美元点store点点点price或book方括号星号点price。取第二本书的作者:美元点store点book方括号一点author。筛选价格低于十的书:美元点store点book方括号问号at点price小于十圆括号。取整个JSON里所有叫isbn的字段:美元点点点isbn。

这些表达式在Jayway、jsonpath-ng里都能直接跑,结果返回匹配的节点列表。注意不同实现对过滤语法和切片边界支持有差异,跨语言用先查实现文档。

常见问题

【JSONPath和jq什么区别?】jq是命令行JSON处理工具,有自己的语法,功能更强能做管道、映射、算术。JSONPath只查询不转换,语法更简单。需要复杂处理用jq,只定位取值用JSONPath。两者定位重叠但不替代。

【过滤表达式里怎么写与或?】用逻辑与或非符号或and or关键字,看实现。Jayway用双竖线和双与号。比如book方括号问号at点price小于十且at点category等于fiction圆括号,用双与号连接两个条件。

【JSONPath能修改JSON吗?】标准JSONPath只读查询不修改。但有些实现扩展了赋值能力,能改值。标准用法是取值,改值用代码更清晰,别依赖扩展。

【递归下降性能怎么样?】递归下降会遍历整个结构找匹配,数据量大时有性能开销。对超大JSON或高频调用场景,知道结构后用精确路径更快,递归下降留给结构未知或调试时用。

标签: JSONPath JSON 数据查询 语法

抱歉,评论功能暂时关闭!