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

JSONPath: Extracting subset of array produces weird results

我有这个 json:

{
  "push": {
    "changes": [
      {
        "commits": [
          {
            "hash": "b194ab92186b94de3f9493818c353e9bbedb38d4"
          }
        ]
      }
    ]
  }
}

而且,我有以下 jq,代码运行良好

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

产生我想要的东西。

我现在尝试使用等效的 JSONPath,这就是它变得奇怪的地方: 如果我 try it here,我会得到数组大小为 1 的散列:

$.push.changes[*].commits[*].hash
[
  "b194ab92186b94de3f9493818c353e9bbedb38d4"
]

所以,那个产量和数组,然后我可以索引那个数组,对吧?:

$.push.changes[*].commits[*].hash[0]
[
  "b"
]

我收到字母 b - 所以现在它将字符串视为字符数组。

所以,这可能是一个实施问题。我在 groovy 中尝试了相同的路径表达式,但我得到了一些不同的东西:

在jsonpath.groovy

@Grab(group = 'com.jayway.jsonpath', module = 'json-path', version = '2.4.0')
import com.jayway.jsonpath.*

stuff = JsonPath.parse(new File('push.json')).read('$.push.changes[*].commits[*].hash')
println(stuff)
$ groovy jsonpath.groovy

[b194ab92186b94de3f9493818c353e9bbedb38d4]

好的,我们又得到了数组。现在,让我们获取 1 个元素:

@Grab(group = 'com.jayway.jsonpath', module = 'json-path', version = '2.4.0')
import com.jayway.jsonpath.*

stuff = JsonPath.parse(new File('push.json')).read('$.push.changes[*].commits[*].hash[0]')
println(stuff)
$ groovy jsonpath.groovy 
[]

所以现在,好像数组什么都没有了?!

那么,如何将这个单个数组项作为路径表达式?

你的问题不够明确。但是,你表达的行为是正确的。您的 commits 是一个数组,因此您可以像 commits[*]commits[0] 那样使用它。但是 hash 字段不是数组。因此 JSONPath 将其视为 arrays of characters

我猜你想从 commits 数组中得到正确的 hash。所以你只需要你的表达方式是这样的:

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

然后假设您的 JSON 对象是这样的:

{
  "push": {
    "changes": [
      {
        "commits": [
          {
            "hash": "b194ab92186b94de3f9493818c353e9bbedb38d4"
          },
          {
              "hash":"secondHash"
          }
        ]
      }
    ]
  }
}

结果将是:

[
  "secondHash"
]

您可以使用:

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

获取该层次结构中的“第一个”哈希。

[*] 的行为类似于 Groovy

中的展开运算符