jmespath 学习

jmespath库的功能和jsonpath比较相似, 以前不知到这个,他们都是用来从json中抽取数据的

 

参考:其中有4篇文章介绍jmespath

https://www.cnblogs.com/pingguo-softwaretesting/category/1789411.html

作者还有一部分没有讲到,那就过滤器

 

这个页面中,可以学习怎么使用jmespath,可以在学习的过程进行练习, https://jmespath.org/tutorial.html [英文的]

 

这里仅记录下第一个连接中未介绍的部分,其他请参考上面的2个链接吧。

 

对投影进行过滤:【仅能用于过滤list】

表达能力比较弱,还是举例子吧

{
  "machines": [
    {"name": "a", "state": "running"},
    {"name": "b", "state": "stopped"},
    {"name": "c", "state": "running"}
  ]
}

表达式: machines[?state=='running'].name
结果为:[ "a",  "c" ]


表达式: machines[?state=='running']
结果为:
[
  {
    "name": "a",
    "state": "running"
  },
  {
    "name": "c",
    "state": "running"
  }
]

上面的代码示例,说明我们可以通过  LHS [? <expression> <comparator> <expression>] RHS  的格式来对list中的值进行过滤。

表达式中去掉name后,就是我们的过滤器产生的完整的结果

过滤表达式中的可以使用的操作符包括: ==, !=, <, <=, >, >=.

 

管道表达式

有一个问题需要jmespath帮我们解决。

{
  "people": [
    {"first": [1,2]},
    {"first": [3,4]},
    {"first": [5,6]},
    {"missing": "different"}
  ],
  "foo": {"bar": "baz"}
}

目的:我想获取第二个first下对应的值

表达式: people[*].first[1]

结果: 
[
  2,
  4,
  6
]

这是因为[1]并不是去获取第二个first下对应的值,而是对所有的first的值都取索引1对应的值

-----------------------------------------------------------------------------------------

使用管道可以解决这个问题!!

表达式: people[*].first | [0]

| 是管道符, 告诉jmespath,投影操作到此为止,此时投影的结果作为一个新的数据开始进行取值操作了

结果:
[
  1,
  2
]

 

生成新的列表或字典

以上我们学习到的,都仅仅是数据的抽取,或者投影(转换成list)

jmespath可以让我们,根据需要生成新的list或者dict

例子1: 我们根据原始数据生成一组新的list

{
  "people": [
    {
      "name": "a",
      "state": {"name": "up"}
    },
    {
      "name": "b",
      "state": {"name": "down"}
    },
    {
      "name": "c",
      "state": {"name": "up"}
    }
  ]
}

表达式: people[].[name, state.name]

结果:
[
  [
    "a",
    "up"
  ],
  [
    "b",
    "down"
  ],
  [
    "c",
    "up"
  ]
]


表达式: people[].[name, state.name1]

结果:
[
  [
    "a",
    None
  ],
  [
    "b",
    None
  ],
  [
    "c",
    None
  ]
]

需要注意的是,即使没有找到name,或者state.name 那么结果也不会是空列表,会用None填充

例子2: 我们根据原始数据生成一组新的dict

{
  "people": [
    {
      "name": "a",
      "state": {"name": "up"}
    },
    {
      "name": "b",
      "state": {"name": "down"}
    },
    {
      "name": "c",
      "state": {"name": "up"}
    }
  ]
}

表达式: people[].{Name: name, State: state.name}

结果:
[
  {
    "Name": "a",
    "State": "up"
  },
  {
    "Name": "b",
    "State": "down"
  },
  {
    "Name": "c",
    "State": "up"
  }
]

 

使用函数

JMESPath可以支持函数表达式,buildin的函数,可以从这里找到 buildin

{
  "people": [
    {
      "name": "Simon",
      "age": 30,
      "state": {"name": "up"}
    },
    {
      "name": "wenson",
      "age": 50,
      "state": {"name": "down"}
    },
    {
      "name": "bigben",
      "age": 40,
      "state": {"name": "up"}
    }
  ]
}


表达式:length(people)
结果: 3


表达式:max_by(people, &age).name
结果: "wenson"


表达式:people[?contains(name, 'on') == `true`].name
结果:
[
  "Simon",
  "wenson"
]





{
  "myarray": [
    "foo",
    "foobar",
    "barfoo",
    "bar",
    "baz",
    "barbaz",
    "barfoobaz"
  ]
}

表达式: myarray[?contains(@, 'foo') == `true`]
结果:
[
  "foo",
  "foobar",
  "barfoo",
  "barfoobaz"
]

这个@好像仅能用在列表项是字符串的情况,如果列表项是dict那么需要指定要进行比较的key
@代表列表中所有的项

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值