什么是JMESPath

看命名你应该能猜出JMESPath的作用,跟JSONPath类似,JMESPath是JSON的查询语言,你可以用它分析、转换和选择性的提取JSON数据。

JMESPath 语法

1. 基本表达式

  • 标识符:最基本的表达式,提取单个属性值;
  • 点表达式:提取JSON对象中的嵌套值;
  • 索引表达式:选择列表中的特定元素

如果JSON文档中不存在标识符,则返回null值,我们来看一些例子:

JSON JMESPath 结果
{"a": "foo", "b": "bar", "c": "baz"} c "baz"
{"a": {"b": {"c": {"d": "value"}}}} a.b.c.d "value"
["a", "b", "c", "d", "e", "f"] [2] "c"
{"d": [0, [1, 2]]} d[1][0] 1

2. 切片(Slicing)

使用切片选择列表的连续子集。 JMESPath跟Python切片语法一样。你可以指定起始索引(包含)和结束索引(不包含),我们来看一些例子,通过切片提取下面这个数组:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
JMESPath 说明 结果
[0:3][:3] 从前到后或取3个元素 [0, 1, 2]
[8:10][8:] 或取从8~10的元素 [8, 9]
[::2][0:10:2] 表达式[start:stop:step],以步长2获取所有元素 [0, 2, 4, 6, 8]
[::-1][10:0:-1] 倒序获取所有元素 [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

3. 推测(Projections)

推测是JMESPath的关键特性之一,它允许你将表达式应用于元素集合。JMESPath有五种推测:

  • 列表推测(List Projections)
  • 切片推测(Slice Projections)
  • 对象推测(Object Projections)
  • 展平推测(Flatten Projections)
  • 过滤推测(Filter Projections)

3.1 列表和切片推测

列表推测结果为空时,返回[]空数组。

{
  "people": [
    {"first": "James", "last": "d"},
    {"first": "Jacob", "last": "e"},
    {"first": "Jayden", "last": "f"},
    {"missing": "different"}
  ],
  "foo": {"bar": "baz"}
}
JMESPath 说明 结果
people[*].first 获取people下所有first属性的值 ["James", "Jacob", "Jayden"]
people[:2].first 获取people下前两个first属性的值 ["James", "Jacob", "Jayden"]

3.2 对象推测

{
  "ops": {
    "functionA": {"numArgs": 2},
    "functionB": {"numArgs": 3},
    "functionC": {"variadic": true}
  }
}
JMESPath 说明 结果
ops.*.numArgs 获取ops下所有numArgs属性的值 [2, 3]
ops.*.variadic 获取ops下所有variadic属性的值 [true]

3.3 打平推测

{
  "reservations": [
    {
      "instances": [
        {"state": "running"},
        {"state": "stopped"}
      ]
    },
    {
      "instances": [
        {"state": "terminated"},
        {"state": "runnning"}
      ]
    }
  ]
}
JMESPath 说明 结果
reservations[*].instances[*].state 获取reservations下所有instances的state属性的值 [["running","stopped"],["terminated","runnning"]]
[
  [0, 1],
  2,
  [3],
  4,
  [5, [6, 7]]
]
JMESPath 说明 结果
[] 打平/压缩数组 [0, 1, 2, 3, 4, 5, [6,7]]

3.4 过滤推测

{
  "machines": [
    {"name": "a", "state": "running"},
    {"name": "b", "state": "stopped"},
    {"name": "b", "state": "running"}
  ]
}
JMESPath 说明 结果
machines[?state=='running'].name 获取machines列表下状态为running的name属性 ["a", "b"]

过滤器表达式,支持常用的比较符,如==,!=,<,<=,>,> =。

4. 内置函数

JMESPath内置了丰富的函数,可以在不同的数据类型上运行,下面的每个函数都对应了自己的语法,描述了输入的类型和输出的类型:

  • abs:返回参数的绝对值
number abs(number $value)
  • avg:返回参数的平均值
number avg(array[number] $elements)
  • contains:判断是否包含在$search的内容
boolean contains(array|string $subject, any $search)
  • ceil:向上取整。
number ceil(number $value)
  • ends_with:判断是否以$prefix结尾
boolean ends_with(string $subject, string $prefix)
  • floor:向下取整
number floor(number $value)
  • join:按指定分隔符分隔数组为字符串
string join(string $glue, array[string] $stringsarray)
  • keys:返回对象的key列表
array keys(object $obj)
  • length:返回指定对象的长度
number length(string|array|object $subject)
  • map:将expr应用于elements数组中的每个元素并返回结果数组。
array[any] map(expression->any->any expr, array[any] elements)
  • max:返回数组中的最大值
number max(array[number]|array[string] $collection)
  • max_by:使用表达式expr作为比较器返回数组中的最大元素
max_by(array elements, expression->number|expression->string expr)
  • merge:合并对象
object merge([object *argument, [, object $...]])
  • min:返回数组中的最小值
number min(array[number]|array[string] $collection)
  • min_by:使用表达式expr作为比较器返回数组中的最小元素
min_by(array elements, expression->number|expression->string expr)
  • not_null:返回不为null的第一个参数
any not_null([any $argument [, any $...]])
  • reverse:反转数组
array reverse(string|array $argument)
  • sort:数组排序
array sort(array[number]|array[string] $list)
  • sort_by:使用表达式expr作为比较器对数组进行排序
sort_by(array elements, expression->number|expression->string expr)
  • starts_with:判断是否以prefix开始
boolean starts_with(string $subject, string $prefix)
  • sum:返回数组的总和。
number sum(array[number] $collection)
  • to_array:元素转数组
array to_array(any $arg)
  • to_string:元素转字符串
string to_string(any $arg)
  • to_number:元素转数值
number to_number(any $arg)
  • type:返回指定参数的类型
string type(array|object|string|number|boolean|null $subject)
  • values:返回对象的所有值
array values(object $obj)

JMESPath 库

各种语言都实现了JMESPath规范,下表是JMESPath语言库以及规范级别,规范级别代办库可以通过的规范测试。

语言 库名 规范级别
Python jmespath.py 完全支持
PHP jmespath.php 完全支持
Javascript jmespath.js 完全支持
Ruby jmespath.rb 完全支持
Lua jmespath.lua 完全支持
Go go-jmespath 完全支持
Java jmespath-java 完全支持
Rust jmespath.rs 完全支持
DotNet jmespath.net 完全支持

除了上面的JMESPath库之外,还有许多其它JMESPath工具。

工具 说明
jmespath.terminal 一个JMESPath交互式终端
jp 跨平台JMESPath命令行工具,在shell脚本中提取和编辑JSON数据非常方便