I have some json that I want to add to based on a walk. A simple example of the json I have is below:
{
"valueSource": "memory",
"dataType": "Boolean",
"alarms": [
{
"setpointA": 1.0,
"name": "Alarm",
"priority": "Diagnostic",
"ackMode": "Auto",
}
],
"name": "Test Alarm",
"value": false,
"tagType": "AtomicTag"
}
I want to add to each object in the "alarms" key's array the following key:
{
"bindType": "Tag",
"value": "[.]<parent.name>.Name"
}
where <parent.name>
is "Test Alarm" in this example which is the parent-of-the-alarm-array-item's "name" key.
I've gotten this jq filter so far that adds the object, but the value
key value is wrong (it's getting the alarm array item's name instead of its parent's name):
walk( if type == "object" and .setpointA then .label = {"bindType":"Tag", "value": "[.]\(.name).Name"} else . end)
Essentially I want this:
{
"valueSource": "memory",
"dataType": "Boolean",
"alarms": [
{
"setpointA": 1.0,
"name": "Alarm",
"priority": "Diagnostic",
"ackMode": "Auto",
"label": {
"bindType": "Tag",
"value": "[.]Test Alarm.Name"
}
}
],
"name": "Test Alarm",
"value": false,
"tagType": "AtomicTag"
}
Here is my jqplay below. It has the final result in the JSON section, where the Result should match this but doesn't at the moment. https://jqplay.org/s/-qHFIWolrD
CodePudding user response:
You cannot reference to parent, you have to save the reference in a variable beforehand, and descend with having access to that variable.
.tags[] |= (
.name as $name
| # rest of your code using $name
walk(
if type == "object" and .setpointA
then .label = {"bindType":"Tag", "value": "[.]\($name).Name"}
else . end
)
)
As you happen to know that the objects are located in the .alarms
array, you could also just iterate over the items, select
only those matching the condition and then assign to their .label
whatever you want (including $name
)
.tags[] |= (
.name as $name
| (.alarms[] | select(has("setpointA"))).label = {
bindType: "Tag", value: "[.]\($name).Name"
}
)
CodePudding user response:
As jq does not allow you to refer to parent object, you need to work on parent level :
jq 'walk(if type == "object" and .alarms and ( .alarms | arrays )
then (.alarms[] | select(.setpointA)).label =
{ bindType: "Tag", value: "[.]\(.name).Name"}
else . end
)' data.json