首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JQ:如何使用jq选择的数据创建JSON对象?

JQ:如何使用jq选择的数据创建JSON对象?
EN

Stack Overflow用户
提问于 2020-04-23 18:05:46
回答 1查看 228关注 0票数 3

我有一个复杂的JSON文件,其中包含数百个“属性”,其类型由"objectTypeAttributeId“标识。

我知道objectTypeAttributeId=328的意思是滴答作响,objectTypeAttributeId=329包含主机名数组等等。

文件的简化版本如下:

代码语言:javascript
复制
{
  "objectEntries": [
    {
      "attributes": [
        {
          "id": 279792,
          "objectTypeAttributeId": 328,
          "objectAttributeValues": [
            {
              "displayValue": "ITSM-24210"
            }
          ]
        },
        {
          "id": 279795,
          "objectTypeAttributeId": 329,
          "objectAttributeValues": [
            {
              "displayValue": "testhost1"
            },
            {
              "displayValue": "testhost2"
            }
          ]
        },
        {
          "id": 279793,
          "objectTypeAttributeId": 330,
          "objectAttributeValues": [
            {
              "displayValue": "28.02.2020 11:45"
            }
          ]
        }
      ]
    }
  ]
}

我需要使用特定的值(根据输入JSON的"objectTypeAttributeId“值)创建输出JSON,格式如下:

代码语言:javascript
复制
{
    "tickets": [
        {
            "ticketid": "ITSM-24210",
            "hostnames": ["testhost1", "testhost2"],
            "date": "28.02.2020 11:45"
        }
    ]
}

我在jq中是新的,在XSLT中,可以使用带有占位符的静态模板来解决选中的值。

我尝试过这种方法,这里有我的jq过滤器:

代码语言:javascript
复制
.objectEntries[].attributes[] |
  {ticketid: select(.objectTypeAttributeId == 328) | .objectAttributeValues[0].displayValue},
  {hostnames: select(.objectTypeAttributeId == 329) | [.objectAttributeValues[].displayValue]},
  {date: select(.objectTypeAttributeId == 330) | .objectAttributeValues[0].displayValue}

但这种做法的结果是:

代码语言:javascript
复制
{
  "ticketid": "ITSM-24210"
}
{
  "hostnames": [
    "testhost1",
    "testhost2"
  ]
}
{
  "date": "28.02.2020 11:45"
}

我随后的所有尝试都是在不返回任何内容的坏掉的jq过滤器或过滤器中格式化输出。

请有什么办法解决这个问题吗?

EN

回答 1

Stack Overflow用户

发布于 2020-04-23 19:10:26

在这里,它不是很漂亮,也许有一个更好的解决方案,但它有效:https://jqplay.org/s/sxussfa2Vj

代码语言:javascript
复制
.objectEntries | {tickets: map(.attributes | 
{ticketID: (reduce .[] as $r (null;  if $r.objectTypeAttributeId == 328 
then $r.objectAttributeValues[0].value else . end)),
date: (reduce .[] as $r (null;  if $r.objectTypeAttributeId == 330
then $r.objectAttributeValues[0].value else . end)), 
hostnames: (reduce .[] as $r ([];  if $r.objectTypeAttributeId == 329 
then $r.objectAttributeValues | map(.value) else . end))})}

这里有很多的解压和重新包装,这些都分散了人们对核心的注意力。您有一系列的入场券(又名条目),在这些上面我们映射。我们必须从数组的不同条目中获取的各种属性,这些属性都是使用reduce完成的。减遍历对象数组,选择正确的对象,并跟踪值。

也许有一个很好的方法,但这已经起作用了,所以你可以继续玩下去,试着简化它。

您最初的解决方案几乎奏效,您在那里做得很好,只需要一张地图:

代码语言:javascript
复制
.objectEntries[].attributes | 
{ticketid: . | map(select(.objectTypeAttributeId == 328))[0] | 
.objectAttributeValues[0].displayValue, 
date: . | map(select(.objectTypeAttributeId == 330))[0] |
.objectAttributeValues[0].displayValue, 
hostnames: . | map(select(.objectTypeAttributeId == 329))[0] | 
[.objectAttributeValues[].displayValue]}

(试试看,它甚至适用于多张票;) https://jqplay.org/s/ydoCgv9vsI

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61394066

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档