JSONPath: 提取数组的子集产生奇怪的结果

huangapple go评论123阅读模式
英文:

JSONPath: Extracting subset of array produces weird results

问题

您可以使用JSONPath表达式来获取单个数组项,但要注意JSONPath和jq的语法有所不同。以下是如何在JSONPath中获取单个数组项的示例表达式:

  1. $.push.changes[0].commits[0].hash

这个表达式将返回您期望的单个哈希值。

请注意,JSONPath索引是从0开始的,所以我们使用[0]来获取数组中的第一个元素。与jq不同,JSONPath不会将字符串视为字符数组,所以您不需要额外的[0]来获取单个字符。

希望这可以帮助您解决问题。

英文:

I have this json:

  1. {
  2. "push": {
  3. "changes": [
  4. {
  5. "commits": [
  6. {
  7. "hash": "b194ab92186b94de3f9493818c353e9bbedb38d4"
  8. }
  9. ]
  10. }
  11. ]
  12. }
  13. }

And, I have the follow jq, code that works fine

  1. cbongiorno at 5cg6203867 in ~/dev/sterling/pipeaas on master [+!?]
  2. $ jq -re '.push.changes[].commits[].hash ' push.json # golden hash
  3. b194ab92186b94de3f9493818c353e9bbedb38d4

which produces what I want.

I now try to use the JSONPath equivalent and this is where it gets strange:
If I try it here, I get and array size 1 with my hash:

  1. $.push.changes[*].commits[*].hash
  2. [
  3. "b194ab92186b94de3f9493818c353e9bbedb38d4"
  4. ]

So, that that yields and array, then I can just index that array, right?:

  1. $.push.changes[*].commits[*].hash[0]
  2. [
  3. "b"
  4. ]

I get the letter b - so now it's treating the string as a character array.

So, maybe it's an implementation problem. I tried this same path expression in groovy and I get something yet also different:

in jsonpath.groovy

  1. @Grab(group = 'com.jayway.jsonpath', module = 'json-path', version = '2.4.0')
  2. import com.jayway.jsonpath.*
  3. stuff = JsonPath.parse(new File('push.json')).read('$.push.changes[*].commits[*].hash')
  4. println(stuff)
  1. $ groovy jsonpath.groovy
  2. [b194ab92186b94de3f9493818c353e9bbedb38d4]

Ok, we have our array again. Now, let's get that 1 element:

  1. @Grab(group = 'com.jayway.jsonpath', module = 'json-path', version = '2.4.0')
  2. import com.jayway.jsonpath.*
  3. stuff = JsonPath.parse(new File('push.json')).read('$.push.changes[*].commits[*].hash[0]')
  4. println(stuff)
  1. $ groovy jsonpath.groovy
  2. []

So now, it's like the array has nothing at all?!

So, how do I get this single array item as a path expression?

答案1

得分: 1

你的问题不够清晰。但是,你的表达行为是正确的。你的 commits 是一个数组,所以你可以像 commits[*]commits[0] 一样操作它。但是 hash 字段不是数组。因此,JSONPath 将其视为 字符数组

我猜你想从 commits 数组中获取正确的 hash。所以你只需要将你的表达式修改为:

$.push.changes[*].commits[1].hash

假设你的 JSON 对象如下:

  1. {
  2. "push": {
  3. "changes": [
  4. {
  5. "commits": [
  6. {
  7. "hash": "b194ab92186b94de3f9493818c353e9bbedb38d4"
  8. },
  9. {
  10. "hash":"secondHash"
  11. }
  12. ]
  13. }
  14. ]
  15. }
  16. }

结果将是:

  1. [
  2. "secondHash"
  3. ]
英文:

Your question is not clear enough. But, the behavior of your expression is correct. your commits is an array so you can behave it like commits[*] or commits[0]. But the hash field is not array. Because of that JSONPath treats it like arrays of characters.

I guess you want to get the right hash from commits array. so you just need your expression to be like:

$.push.changes[*].commits[1].hash

then assuming your JSON objet is like:

  1. {
  2. "push": {
  3. "changes": [
  4. {
  5. "commits": [
  6. {
  7. "hash": "b194ab92186b94de3f9493818c353e9bbedb38d4"
  8. },
  9. {
  10. "hash":"secondHash"
  11. }
  12. ]
  13. }
  14. ]
  15. }
  16. }

the result would be :

  1. [
  2. "secondHash"
  3. ]

答案2

得分: 1

你可以使用以下代码来获取该层次结构中的“第一个”哈希值:

  1. $.push.changes[0].commits[0].hash

[*] 的行为类似于Groovy中的扩展操作符。

英文:

You can use:

  1. $.push.changes[0].commits[0].hash

To get the "first" hash in that hierarchy.

[*] behaves like the spread-operator in Groovy

huangapple
  • 本文由 发表于 2020年7月29日 07:19:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/63144161.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定