Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Json 使用JQ删除具有特定键值对的父元素_Json_Jq_Key Value_Del - Fatal编程技术网

Json 使用JQ删除具有特定键值对的父元素

Json 使用JQ删除具有特定键值对的父元素,json,jq,key-value,del,Json,Jq,Key Value,Del,我需要根据某些键值从json文件中删除元素。这是我试图处理的文件 { "element1": "Test Element 1", "element2": { "tags": "internal", "data": { "data1": "Test Data 1", "data2&q

我需要根据某些键值从json文件中删除元素。这是我试图处理的文件

{
  "element1": "Test Element 1",
  "element2": {
    "tags": "internal",
    "data": {
      "data1": "Test Data 1",
      "data2": "Test Data 2"
    }
  },
  "element3": {
    "function1": {
      "tags": [
        "new",
        "internal"
      ]
    },
    "data3": "Test Data 3",
    "data4": "Test Data 4"
  },
  "element4": {
    "function2": {
      "tags": "new"
    },
    "data5": "Test Data 5"
  }
}
我想删除所有具有值为“internal”的“tag”的元素。所以结果应该是这样的:

{
  "element1": "Test Element 1",
  "element4": {
    "function2": {
      "tags": "new"
    },
    "data5": "Test Data 5"
  }
}
我尝试了各种方法,但我就是不能用jq完成。有什么想法吗?谢谢

只是为了增加一些复杂性。让我们假设json是:

{
  "element1": "Test Element 1",
  "element2": {
    "tags": "internal",
    "data": {
      "data1": "Test Data 1",
      "data2": "Test Data 2"
    }
  },
  "element3": {
    "function1": {
      "tags": [
        "new",
        "internal"
      ]
    },
    "data3": "Test Data 3",
    "data4": "Test Data 4"
  },
  "element4": {
    "function2": {
      "tags": "new"
    },
    "data5": "Test Data 5"
  },
  "structure1" : {
    "substructure1": {
      "element5": "Test Element 5",
      "element6": {
        "tags": "internal",
        "data6": "Test Data 6"
      }
    }
  }
}
我想得到

{
  "element1": "Test Element 1",
  "element4": {
    "function2": {
      "tags": "new"
    },
    "data5": "Test Data 5"
  },
  "structure1" : {
    "substructure1": {
      "element5": "Test Element 5",
    }
  }
}
不容易,只有使用下面的复杂布尔表达式,才能可靠地查找具有
标记
键(其值为字符串
内部
),或元素为字符串
内部
的数组的元素

一旦找到,可以使用内置的
del
删除它们

del(.[] | first(select(recurse
  | objects
  | has("tags") and (.tags
    | . == "internal" or (
      type == "array" and index("internal")
    )
  )
)))

为了清晰起见,下面的解决方案是用一个helper函数编写的。helper函数使用
any
来提高效率,其定义是为了增加一些通用性

要理解该解决方案,了解带有_条目的
和中缀
/
操作符将很有帮助,这两个都在jq手册中进行了解释

# Does the incoming JSON value contain an object which has a .tags
# value that is equal to $value or to an array containing $value ?
def hasTag($value):
  any(.. | select(type=="object") | .tags;
      . == $value or (type == "array" and index($value)));
假设顶级JSON实体是JSON对象,我们现在可以简单地编写:

with_entries( select( .value | hasTag("internal") | not) )

我想我找到了解决更复杂问题的方法。我现在正在跑步:

walk(if type == "object" and has("tags") and (.tags  | . == "internal" or (type == "array" and index("internal"))) then del(.) else . end) | delpaths([paths as $path | select(getpath($path) == null) | $path])

这将删除所有包含“internal”作为“tag”的元素。

如果我只想删除包含“tag”=“internal”的父元素而不是整个元素,我该怎么办?我不明白,你说的父元素和整个元素是什么意思?让我们假设有一个元素“`”structure1:{“子结构1”:{“Element 5”:“Test Element 5”,“Element 6”:{“tags”:“internal”,“data6”:“Test Data 6”}“```其中我只想删除'element6',而不想删除'element5'。您的编辑使这个问题比现在更广泛、更不清楚。是什么使一个对象成为一个元素?与它相关联的键中的前缀
元素
?一个元素包含什么?多个函数,每个函数包含
标记
,还是只有一个函数和数据?包含
element1
element2
等的对象是否包含非元素的任何其他键?