jsonpath模块01

2020-12-17  本文已影响0人  阿登20

JSONPath 表达式

JSONPath 是参照,xpath表达式来解析xml文档的方式,json数据结构通常是匿名的并且不一定需要有根元素。JSONPaht 用一个抽象的名字$来表示最外层对象。

JOSNPath 表达式可以使用. 符号如下:

$.store.book[0].title

或者使用[] 符号

$['store']['book'][0]['title']

从输入路径来看。内部或者输出的路径都会转化成-符号。

JSONPath 允许使用通配符 * 表示所以的子元素名和数组索引。还允许使用 '..' 从E4X参照过来的和数组切分语法 [start:end:step]是从ECMASCRIPT 4 参照过来的。

表达式在下面的脚本语言中可以使用显示的名称或者索引:

$.store.book[(@.length-1)].title

使用'@'符号表示当前的对象,?(<判断表达式>) 使用逻辑表达式来过滤。

$.store.book[?(@.price < 10)].title

这里有个表格,说明JSONPath语法元素和对应XPath元素的对比。

XPath JSONPath Description
/ $ 表示根元素
. @ 当前元素
/ . or [] 子元素
.. n/a 父元素
// .. 递归下降,JSONPath是从E4X借鉴的。
* * 通配符,表示所有的元素
@ n/a 属性访问字符
[] [] 子元素操作符
| [,] 连接操作符在XPath 结果合并其它结点集合。JSONP允许name或者数组索引。
n/a [start:end:step] 数组分割操作从ES4借鉴。
[] ?() 应用过滤表示式
n/a () 脚本表达式,使用在脚本引擎下面。
() n/a Xpath分组

XPath还有很多的语法(本地路径,操作符,和函数)没有列在这里。只要知道xpath和jsonpath脚本之中的不同点就行了。

SONPath 例子

接下我们看jsonpath表示的例子。下面是一个简单的json数据结构代表一个书店(原始的xml文件是)

{ "store": {
    "book": [ 
      { "category": "reference",
        "author": "Nigel Rees",
        "title": "Sayings of the Century",
        "price": 8.95
      },
      { "category": "fiction",
        "author": "Evelyn Waugh",
        "title": "Sword of Honour",
        "price": 12.99
      },
      { "category": "fiction",
        "author": "Herman Melville",
        "title": "Moby Dick",
        "isbn": "0-553-21311-3",
        "price": 8.99
      },
      { "category": "fiction",
        "author": "J. R. R. Tolkien",
        "title": "The Lord of the Rings",
        "isbn": "0-395-19395-8",
        "price": 22.99
      }
    ],
    "bicycle": {
      "color": "red",
      "price": 19.95
    }
  }
}
XPath JSONPath 结果
/store/book/author $.store.book[*].author 书点所有书的作者
//author $..author 所有的作者
/store/* $.store.* store的所有元素。所有的bookst和bicycle
/store//price $.store..price store里面所有东西的price
//book[3] $..book[2] 第三个书
//book[last()] $..book[(@.length-1)] 最后一本书
//book[position()<3] $..book[0,1]``$..book[:2] 前面的两本书。
//book[isbn] $..book[?(@.isbn)] 过滤出所有的包含isbn的书。
//book[price<10] $..book[?(@.price<10)] 过滤出价格低于10的书。
//* $..* 所有元素。

http://www.atoolbox.net/Tool.php?Id=792 在线练习网址

jsonpath操作符:

操作 说明
$ 查询根元素。这将启动所有路径表达式。
@ 当前节点由过滤谓词处理。
* 通配符,必要时可用任何地方的名称或数字。
.. 深层扫描。 必要时在任何地方可以使用名称。
.<name> 点,表示子节点
['<name>' (, '<name>')] 括号表示子项
[<number> (, <number>)] 数组索引或索引
[start:end] 数组切片操作
[?(<expression>)] 过滤表达式。 表达式必须求值为一个布尔值。

函数

函数可以在路径的尾部调用,函数的输出是路径表达式的输出,该函数的输出是由函数本身所决定的。

函数 描述 输出
min() 提供数字数组的最小值 Double
max() 提供数字数组的最大值 Double
avg() 提供数字数组的平均值 Double
stddev() 提供数字数组的标准偏差值 Double
length() 提供数组的长度 Integer

过滤器运算符

过滤器是用于筛选数组的逻辑表达式。一个典型的过滤器将是[?(@.age > 18)],其中@表示正在处理的当前项目。 可以使用逻辑运算符&&和||创建更复杂的过滤器。 字符串文字必须用单引号或双引号括起来([?(@.color == 'blue')] 或者 [?(@.color == "blue")]).

操作符 描述
== left等于right(注意1不等于'1')
!= 不等于
< 小于
<= 小于等于
> 大于
>= 大于等于
=~ 匹配正则表达式[?(@.name =~ /foo.*?/i)]
in 左边存在于右边 [?(@.size in ['S', 'M'])]
nin 左边不存在于右边
size (数组或字符串)长度
empty (数组或字符串)为空

接下来我们就用java代码来写一个案例:

Java操作示例

JSON

{ "store": {
    "book": [ 
      { "category": "reference",
        "author": "Nigel Rees",
        "title": "Sayings of the Century",
        "price": 8.95
      },
      { "category": "fiction",
        "author": "Evelyn Waugh",
        "title": "Sword of Honour",
        "price": 12.99
      },
      { "category": "fiction",
        "author": "Herman Melville",
        "title": "Moby Dick",
        "isbn": "0-553-21311-3",
        "price": 8.99
      },
      { "category": "fiction",
        "author": "J. R. R. Tolkien",
        "title": "The Lord of the Rings",
        "isbn": "0-395-19395-8",
        "price": 22.99
      }
    ],
    "bicycle": {
      "color": "red",
      "price": 19.95
    }
  }
}
JsonPath (点击链接测试) 结果
$.store.book[*\].author 获取json中store下book下的所有author值
$..author 获取所有json中所有author的值
$.store.* 所有的东西,书籍和自行车
$.store..price 获取json中store下所有price的值
$..book[2] 获取json中book数组的第3个值
$..book[-2] 倒数的第二本书
$..book[0,1] 前两本书
$..book[:2] 从索引0(包括)到索引2(排除)的所有图书
$..book[1:2] 从索引1(包括)到索引2(排除)的所有图书
$..book[-2:] 获取json中book数组的最后两个值
$..book[2:] 获取json中book数组的第3个到最后一个的区间值
$..book[?(@.isbn)] 获取json中book数组中包含isbn的所有值
$.store.book[?(@.price < 10)] 获取json中book数组中price<10的所有值
$..book[?(@.price <= $['expensive'])] 获取json中book数组中price<=expensive的所有值
$..book[?(@.author =~ /.*REES/i)] 获取json中book数组中的作者以REES结尾的所有值(REES不区分大小写)
$..* 逐层列出json中的所有值,层级由外到内
$..book.length() 获取json中book数组的长度

案例:

{
    "data": {
        "customConfigs": [
            {
                "key": "pushType",
                "value": "YC"
            },
            {
                "key": "commitType",
                "value": "YC"
            },
            {
                "key": "outerSource",
                "value": "333"
            },
            {
                "key": "channelSource",
                "value": "444"
            },
            {
                "key": "mediaSource",
                "value": "555"
            },
            {
                "key": "name",
                "value": "1"
            },
            {
                "key": "city",
                "value": "1"
            },
            {
                "key": "forceQuickFlag",
                "value": "1"
            },
            {
                "key": "carFinance",
                "value": "1"
            },
            {
                "key": "source",
                "value": "xezdzdxKD"
            }
        ],
        "flowTarget": "1"
    },
    "grayPackages": "",
    "jumpUrl": "",
    "responseCode": "000000",
    "responseMsg": "成功"
}

对嵌套列表的字典的处理使用过滤表达式 [?(@.key>123)]

image-20211013101203446

image-20211013101838009

对嵌套列表的字典的处理使用 正则表达式 [?(@.key =~ /.*pe/i)]

=~ / 后面跟正在表达式 /i忽略大小写

[*] 对列表结果取所有

image-20211013103523519

length获取结果是列表的长度

image-20211013103607090

结果是字符串的,获取长度

image-20211013103704415

结果是列表 切片取多个值

image-20211013104036322

对前面结果是字典的,通过[key1,key2....]取多个值

image-20211013104217566

注意取列表最后写法误区

[@.length -1] 这种写法是错的 正确是[(@.length -1)] 必须要用括号包起来才是表达式

上一篇下一篇

猜你喜欢

热点阅读