访问带有未知密钥的嵌套JSON



我有以下json数据:

{"results":
{"xxxxxx":{"id":"as23","status":1,"res":"xsd"},
{"xxxxxx":{"id":"fds34","status":2,"res":"dox"},
{"xxxxxx":{"id":"as23","status":1,"res":"kog"},
{"xxxxxx":{"id":"dgs5","status":2,"res":"dox"},
{"xxxxxx":{"id":"as23","status":2,"res":"dox"},
{"xxxxxx":{"id":"as23","status":1,"res":"dox"}

清单很长,但你明白了。我想要的是查找每个包含idas23的对象,并计算其中有多少对象的状态为1

所以,我在HomeAssistant中使用这个作为休息传感器,我的过滤器表达式如下:

{{ value_json.results|selectattr("id", "==", "as23")|selectattr("status", "eq", 1)|list|length }}

我的问题是:我不知道xxxxxx的值是什么,它们可能不同,并且仍然包含idas23
如何实现这一点?

假设JSON的正确版本为:

{
"results":[
{
"xxxxxx":{
"id":"as23",
"status":1,
"res":"xsd"
}
},
{
"xxxxxx":{
"id":"fds34",
"status":2,
"res":"dox"
}
},
{
"xxxxxx":{
"id":"as23",
"status":1,
"res":"kog"
}
},
{
"xxxxxx":{
"id":"dgs5",
"status":2,
"res":"dox"
}
},
{
"xxxxxx":{
"id":"as23",
"status":2,
"res":"dox"
}
},
{
"xxxxxx":{
"id":"as23",
"status":1,
"res":"dox"
}
}
]
}

借助过滤器json_query和JMESPath查询语言,可以很容易地实现您的需求,它们可以帮助您在属性上实现通配符。

给定调试任务:

- debug:
var: >-
value_json | json_query(
'length(results[].*[] | [?id == `as23` && status == `1`])'
)

这将产生预期的:

ok: [localhost] => 
? |-
value_json | json_query(
'length(results[].*[] | [?id == `as23` && status == `1`])'
)
: '3'

根据@β.εηιτ.βε的答案,这可以在没有json_query的情况下实现(如果你不想/不能使用pip install jmespath(,只使用核心函数。

使用与@βεηιτ.βε的答案相同的假设正确json结构,以下任务:

- debug:
msg: "{{ 
value_json.results | 
map('dict2items') | 
map('map', attribute='value') |
flatten |
selectattr('id', '==', 'as23') |
selectattr('status', '==', 1)
}}"

提供:

TASK [debug] ***************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
"msg": [
{
"id": "as23",
"res": "xsd",
"status": 1
},
{
"id": "as23",
"res": "kog",
"status": 1
},
{
"id": "as23",
"res": "dox",
"status": 1
}
]
}

最新更新