英文:
JSONPath: Extracting subset of array produces weird results
问题
您可以使用JSONPath表达式来获取单个数组项,但要注意JSONPath和jq的语法有所不同。以下是如何在JSONPath中获取单个数组项的示例表达式:
$.push.changes[0].commits[0].hash
这个表达式将返回您期望的单个哈希值。
请注意,JSONPath索引是从0开始的,所以我们使用[0]来获取数组中的第一个元素。与jq不同,JSONPath不会将字符串视为字符数组,所以您不需要额外的[0]来获取单个字符。
希望这可以帮助您解决问题。
英文:
I have this json:
{
"push": {
"changes": [
{
"commits": [
{
"hash": "b194ab92186b94de3f9493818c353e9bbedb38d4"
}
]
}
]
}
}
And, I have the follow jq, code that works fine
cbongiorno at 5cg6203867 in ~/dev/sterling/pipeaas on master [+!?]
$ jq -re '.push.changes[].commits[].hash ' push.json # golden hash
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:
$.push.changes[*].commits[*].hash
[
"b194ab92186b94de3f9493818c353e9bbedb38d4"
]
So, that that yields and array, then I can just index that array, right?:
$.push.changes[*].commits[*].hash[0]
[
"b"
]
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
@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]
Ok, we have our array again. Now, let's get that 1 element:
@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
[]
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 对象如下:
{
"push": {
"changes": [
{
"commits": [
{
"hash": "b194ab92186b94de3f9493818c353e9bbedb38d4"
},
{
"hash":"secondHash"
}
]
}
]
}
}
结果将是:
[
"secondHash"
]
英文:
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:
{
"push": {
"changes": [
{
"commits": [
{
"hash": "b194ab92186b94de3f9493818c353e9bbedb38d4"
},
{
"hash":"secondHash"
}
]
}
]
}
}
the result would be :
[
"secondHash"
]
答案2
得分: 1
你可以使用以下代码来获取该层次结构中的“第一个”哈希值:
$.push.changes[0].commits[0].hash
[*]
的行为类似于Groovy中的扩展操作符。
英文:
You can use:
$.push.changes[0].commits[0].hash
To get the "first" hash in that hierarchy.
[*]
behaves like the spread-operator in Groovy
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论