过滤表达式中的@
JsonPath 中过滤表达式的语法是 [?(<expression>)] ,而 @ 代表过滤表达中当前处理的节点对象。
上示例先:
1 | # jsonpath_ng v1.6.1 |
上面的示例代码中,@.author == 'Robert C. Martin' 使用作者过滤书籍,并获取价格。
@ 通常不是必需的,可以等价省略:
1 | $.store.book[?(@.author == 'Robert C. Martin')] |
独立使用的@
需要另外说明的是,@ 可以不使用在过滤表达式中,它可以独立使用。
我们来看下下面的示例:
1 | $.store.book[*].author |
JsonPath 同时支持 . 导航和 [] 导航,所以前两种访问所有书籍作者的写法是正确的。
因此,在 author 加上 @. 指明是取当前书籍节点的作者,理论也是正确的,只是有点冗余。上面示例中,后两种就是带 @ 的写法,也是正确的。
需要注意的是,带 @ 的写法不允许出现在 [] 导航中,即 $.store.book[*][@.author] 是非法的。
必须的@
@ 很多场景下是冗余的,但不代表它总是可以省略。在进行属性拼接时,@ 就不能省略。比如:
1 | $.store.book[*].(@.author + ' - ' + @.title) |
上面是将书籍作者和标题拼接起来。这里的 @ 是必须的,如果省略为 $.store.book[*].(author + ' - ' + title) 解析程序就会认为是在进行常量字符串的拼接,而不是在取节点数据。这将得到意外的结果:['author - title', 'author - title', 'author - title']。
关于解析环境的说明
笔者试过很多 JsonPath 在线解析工具,大多不支持过滤表达式。
以上的 JsonPath 解析都是在 jsonpath_ng v1.6.1 版本下进行的测试。需要注意的是,解析函数 parse() 是从 jsonpath_ng.ext 中导入的,不要使用 jsonpath_ng 中的那个——因为,它不支持过滤条件式和某些运算,比如字符串拼接😂。