有没有办法为嵌套的python词典定义XPath类型查询.
像这样的东西:
foo = {
'spam':'eggs',
'morefoo': {
'bar':'soap',
'morebar': {'bacon' : 'foobar'}
}
}
print( foo.select("/morefoo/morebar") )
>> {'bacon' : 'foobar'}
Run Code Online (Sandbox Code Playgroud)
我还需要选择嵌套列表;)
这可以通过@ jellybean的解决方案轻松完成:
def xpath_get(mydict, path):
elem = mydict
try:
for x in path.strip("/").split("/"):
try:
x = int(x)
elem = elem[x]
except ValueError:
elem = elem.get(x)
except:
pass
return elem
foo = {
'spam':'eggs',
'morefoo': [{
'bar':'soap',
'morebar': {
'bacon' : {
'bla':'balbla'
}
}
},
'bla'
]
}
print xpath_get(foo, "/morefoo/0/morebar/bacon")
Run Code Online (Sandbox Code Playgroud)
[编辑2016]这个问题和接受的答案是古老的.较新的答案可能比原始答案更好地完成工作.但是我没有测试它们所以我不会改变接受的答案.
使用aws-cli 1.3.6我试图用名称和状态获得一个简单的ec2实例表.我一直在查看--query和JMESpath文档,我已经能够选择Map的"Value"项,其中"Key"项等于Name.这对于获取实例名称很有用.因此,下面的代码似乎工作
aws ec2 describe-instances --output table --query 'Reservations[].Instances[].Tags[?Key==`Name`].Value'
Run Code Online (Sandbox Code Playgroud)
并提供这个:
-------------------
|DescribeInstances|
+-----------------+
| Name1 |
| Name2 |
+-----------------+
Run Code Online (Sandbox Code Playgroud)
但是,如果我想添加状态,事情就会像我预期的那样得到.运用
aws ec2 describe-instances --output table --query 'Reservations[].Instances[].[Tags[?Key==`Name`].Value,State.Name]'
Run Code Online (Sandbox Code Playgroud)
提供
-------------------
|DescribeInstances|
+-----------------+
| Name1 |
| stopped |
| Name2 |
| stopped |
+-----------------+
Run Code Online (Sandbox Code Playgroud)
而不是具有名称和状态的两列表.
如果我们将输出转换为JSON,我们可以看到Tags选项返回一个列表(单元素列表),这可能是问题所在:
[
[
[
"Name1"
],
"stopped"
],
[
[
"Name2"
],
"stopped"
]
]
Run Code Online (Sandbox Code Playgroud)
我无法通过选择第一个元素将此列表转换为标量.这个,不起作用.返回一个空列表作为名称.
aws ec2 describe-instances --output json --query 'Reservations[].Instances[].[Tags[?Key==`Name`].Value[0],State.Name]'
Run Code Online (Sandbox Code Playgroud)
和此一样
aws ec2 describe-instances --output json --query 'Reservations[].Instances[].[Tags[?Key==`Name`].Value[][0],State.Name]'
Run Code Online (Sandbox Code Playgroud)
我解决这个问题的唯一方法是通过join函数.因为我只期待一个元素,所以可以,但我似乎有点hacky.
aws ec2 …Run Code Online (Sandbox Code Playgroud) 我想使用AWS CLI查询存储桶的内容,看看是否存在特定文件,但存储桶包含数千个文件.如何过滤结果以仅显示与模式匹配的键名?例如:
aws s3api list-objects --bucket myBucketName --query "Contents[?Key==*mySearchPattern*]"
Run Code Online (Sandbox Code Playgroud) 问题很简单。如何使用 JMESPath 进行不区分大小写的搜索?
foo假设要在此 JSON 中搜索:
[
"foo",
"foobar",
"barfoo",
"bar",
"baz",
"barbaz",
"FOO"
]
Run Code Online (Sandbox Code Playgroud)
这是区分大小写的搜索查询:
[?contains(@, 'foo')]
Run Code Online (Sandbox Code Playgroud)
它会返回,["foo", "foobar", "barfoo"]但会错过"FOO"。
我正在尝试根据子属性的值过滤jmespath中对象的属性,并且只想包含子属性设置为特定值的那些属性.
基于此示例数据:
{
"a": {
"feature": {
"enabled": true,
}
},
"b": {
},
"c": {
"feature": {
"enabled": false
}
}
}
Run Code Online (Sandbox Code Playgroud)
我想获得一个具有启用该功能的所有属性的对象.
{
"a": {
"feature": {
"enabled": true,
}
}
}
Run Code Online (Sandbox Code Playgroud)
我想我可以使用这个jmespath查询来过滤property. enabled设置为true 的对象.不幸的是,它似乎不起作用而是返回一个空数组.
*[?feature.enabled==`true`]
Run Code Online (Sandbox Code Playgroud)
*.feature.enabled或者*[feature.enabled]只返回没有任何上下文的布尔值.
即使*[?feature.enabled==true ]可以工作,它也只是属性值的数组,但我还需要键(a和c).有没有办法在jmespath中实现这一点?
这是一个ansible playbook的所有部分,所以肯定会有一种方法以不同的方式实现选择(Jinja2模板或自定义插件),但我想尝试jmespath并且会推理它应该能够执行这样的任务.
我的谷歌搜索技能让我失望.如何获取JMESPath中所有JSON对象键的列表?
即如何去:
{"a": 1, "b": 2}
Run Code Online (Sandbox Code Playgroud)
至:
["a", "b"]
Run Code Online (Sandbox Code Playgroud) 我有一个dicts列表,其中包含一个字段中的另一个列表.我想"扁平化"该列表,因此它为每个子元素提供了一个字段(或一些字段)从父项复制到其中.例:
来源数据:
[
{
"name": "A",
"foo": "x",
"bar": 1,
"subelements": [
{
"baz": "xyz",
"foobar": "abc"
},
{
"baz": "zzz",
"foobar": "def"
}
]
},
{
"name": "B",
"foo": "Y",
"bar": 4,
"subelements": [
{
"baz": "yyy",
"foobar": "aaa"
},
{
"baz": "xxx",
"foobar": "bbb"
},
{
"baz": "www",
"foobar": "bbb"
}
]
}
]
Run Code Online (Sandbox Code Playgroud)
预期结果:
[
{
"baz": "xyz",
"foobar": "abc",
"foo": "x"
},
{
"baz": "zzz",
"foobar": "def",
"foo": "x"
},
{
"baz": "yyy",
"foobar": "aaa",
"foo": …Run Code Online (Sandbox Code Playgroud) 我想过滤输出JSON 数组的 Azure CloudShell 命令az ad sp list 的输出,例如通过过滤到 Publisher Name = "ACME"。所有 az 命令都支持接受 JMESPath 表达式的 --query 参数。
我有一个 JMESPath 过滤器:
az ad sp list --query "[?contains(publisherName,'ACME')]" --all
Run Code Online (Sandbox Code Playgroud)
失败并出现错误:
In function contains(), invalid type for value: None, expected one of: ['array', 'string'], received: "null"
Run Code Online (Sandbox Code Playgroud)
我对我的 JMESPath 语法充满信心,因为一个非常相似的表达式可以正常工作:
az ad sp list --query "[?contains(displayName,'ACME')]" --all
Run Code Online (Sandbox Code Playgroud)
我有一个工作正常的空过滤器:
az ad sp list --query "[?publisherName!='null']" --all
Run Code Online (Sandbox Code Playgroud)
但是当我将空过滤器与包含过滤器结合使用时,我仍然收到错误消息:
az ad sp list --query "[?publisherName!='null' && contains(publisherName,'ACME')]" --all
Run Code Online (Sandbox Code Playgroud)
我猜 JMESPath 过滤器不支持布尔运算短路。但是,我没有在 …
我正在尝试创建一个 az cli 查询,它可以评估我是否登录到正确的租户和订阅。我知道我必须使用?和&&运算符,但还无法将它们组合成正确的组合。当我使用下面的行查询单个值时,工作正常:
az account list --query "[?id=='my_subscription_id']" --output json
Run Code Online (Sandbox Code Playgroud)
但是当我尝试下面的任何一行时,它告诉我它是无效的 jmespath_type 值:
az account list --query "[?id=='my_subscription_id' && ?tenantId=='my_tenant_id']" --output json
az account list --query "[(?id=='my_subscription_id') && (?tenantId=='my_tenant_id')]" --output json
Run Code Online (Sandbox Code Playgroud)
当我尝试下面的行时,它给了我错误] was unexpected at this time:
az account list --query "[(?id=='my_subscription_id')&&(?tenantId=='my_tenant_id')]" --output json
Run Code Online (Sandbox Code Playgroud)
我知道这是可以做到的,只是似乎还找不到合适的混合物。
更新信息:
经过进一步的测试,我取得了一些进展,但仍然不完全符合我的预期。假设租户ID是123,我想要的订阅ID是ABC,我的帐户也可以访问订阅ID EFG。运行以下命令时:
az account list --query "[].{subscriptionId:id,tenantId:tenantId}"
Run Code Online (Sandbox Code Playgroud)
我得到输出:
{
"subscriptionId": "ABC",
"tenantId": "123"
},
{
"subscriptionId": "EFG",
"tenantId": "123"
}
Run Code Online (Sandbox Code Playgroud)
我希望运行下面的命令,只会返回匹配的单个记录:
az account list --query "[?id == …Run Code Online (Sandbox Code Playgroud)