Parsing JSON with Powershell's ConvertFrom-Json - arrays

I am trying to parse this JSON using Powershell's ConvertFrom-Json feature, but it seems to truncate the data:
{
"MessagesMonitoring": {
"version": 1,
"description": "Message Description"
},
"data": {
"swindon": {
"totalMessages": 0,
"identifier": [
{
"name": "ET",
"staleCount": 4
},
{
"name": "ET_2",
"staleCount": 4
}
]
},
"Reading": {
"totalMessages": 0,
"identifier": [
{
"name": "J3",
"staleCount": 2
}
]
},
"Yanki": {
"totalMessages": 0,
"identifier": [
{
"name": "UT",
"staleCount": 4
},
{
"name": "UT_2",
"staleCount": 4
}
]
}
}
}
Request:
$request = 'http://localhost:8000/hi.json'
Invoke-WebRequest $request |
ConvertFrom-Json |
Select swindon
Response:
StatusCode : 200 StatusDescription : OK
Content : {
"MessagesMonitoring": {
"version": 1,
"description": "Message Description"
},
"data": {
"swindon": {
"totalMessages": 0,
"identifier": [
{
"na...
Not sure what I may be doing incorrectly. Any advise/guidance on how to parse the JSON into this format would be great.
swindon|identifier|ET|4
swindon|totalMessages|0
swindon|identifier|ET2|4
Reading|identifier|J3|2
Reading|totalMessages|0
Yanki|identifier|UT|4
Yanki|identifier|U_T|4
Yanki|totalMessages|0

You are missing a step. The Content element of the response contains the JSON, so that's what you need to feed into ConvertFrom-Json:
$request = 'http://localhost:8000/hi.json'
$resp = $(Invoke-WebRequest $request).Content | ConvertFrom-Json
Then, within the JSON you have a dictionary, within which the "data" key contains the information I think you're interested in, access it using this syntax:
$resp.data
That should get you started

Related

How to filter JSON data based on another JSON data in typescript

I have 2 JSON Data 1. Payers 2. Rules. I need to filter Payers JSON data based on PayerId from Rules JSON data.
{
"Payers": [
{
"payerId": "12345",
"name": "Test Payer1"
},
{
"payerId": "23456",
"name": "Test Payer2",
},
{
"payerId": "34567",
"name": "Test Payer3"
}}
Rules JSON file
{
"Rules": [
{
"actions": {
"canCopyRule": true
},
"RuleId": 123,
"description": "Test Rule",
"isDisabled": false,
"Criteria": [
{
"autoSecondaryCriteriaId": 8888,
"criteriaType": { "code": "primaryPayer", "value": "Primary Payer" },
"payerId": ["12345", "34567"]
}
]
}
}]}
I need to filter Payers JSON data based on Rules JSON data if PayerID matches
I need output like below
{
"Payers": [
{
"payerId": "12345",
"name": "Test Payer1"
},
{
"payerId": "34567",
"name": "Test Payer3"
}
}
How to filter?
You can use Array.filter like that (based on your data structure):
const filteredPayers = payersObj.Payers.filter((p) => rulesObj.Rules[0].Criteria[0].payerId.includes(p.payerId));
I can't figure out why your Rules json looks like this, I guess you have multiple rules. If so, you will need to iterate over each rule and invoke includes. Same for Criteria.
Code will check each rule and each critirias
and will return payers if payerId found in any of the given rules of any criteria
const payers = {
"Payers": [
{
"payerId": "12345",
"name": "Test Payer1"
},
{
"payerId": "23456",
"name": "Test Payer2",
},
{
"payerId": "34567",
"name": "Test Payer3"
}]}
const rules = {
"Rules": [
{
"actions": {
"canCopyRule": true
},
"RuleId": 123,
"description": "Test Rule",
"isDisabled": false,
"Criteria": [
{
"autoSecondaryCriteriaId": 8888,
"criteriaType": { "code": "primaryPayer", "value": "Primary Payer" },
"payerId": ["12345", "34567"]
}
]
}
]
}
const data = payers.Payers.filter(payer => rules.Rules.findIndex(rule => rule.Criteria.findIndex(criteria => criteria.payerId.includes(payer.payerId)) != -1) !== -1)
console.log(data)

How to add objects to a blank array in a json file using powershell

here is my json body .
{
"source": 2,
"revision": 3,
"description": null,
"triggers": [],
"releaseNameFormat": "Release-$(rev:r)",
"tags": [],
"pipelineProcess": {
"type": 1
},
"properties": {
"DefinitionCreationSource": {
"$type": "System.String",
"$value": "BuildSummary"
},
"System.EnvironmentRankLogicVersion": {
"$type": "System.String",
"$value": "2"
}
},
"id": 5,
"name": "CheckListAPI - CD",
"path": "\\Admin",
"projectReference": null,
"url": "",
"_links": {
"self": {
"href": ""
},
"web": {
"href": ""
}
}
}
I want to add some values inside the brackets at "triggers": [],
What I'm trying to get is:
"triggers":
[
{
"artifactAlias": "_DV_NJ_PIPE",
"triggerConditions": [],
"triggerType": 1
}
],
i tried -replace and replace() saving the json file to local system, but none of them are working, I even tried to edit the json file directly like this but failed.
$alias = $json.triggers
foreach ($artifact in $alias )
{
$artifact.artifactAlias = "_$DefName"
$artifact.triggerConditions = "{}"
$artifact.triggertype = "artifactSource"
}
Please help.
You can import the json file as PowerShell objects, manipulate the structure until it looks the way you want it to and export it back to json format:
$pipeline = Get-Content .\input.json | ConvertFrom-Json
$trigger = [ordered]#{
artifactAlias = "_DV_NJ_PIPE"
triggerConditions = #()
triggerType = 1
}
$pipeline.triggers += $trigger
$pipeline | ConvertTo-Json -Depth 5 | Out-File .\output.json
As it was pointed out in the comments, it is of course also possible to import the trigger definition from a json file instead of building it in a hash table.

Group stream elements and sum a field using JQ

I am trying to group several items by their name based on the JSON-Data. Furthermore I want to calculate the sum of the size. Therefore I am using jq to transforming the data. Attached you see the raw data.
{
"fields": {
"issuetype": {
"name": "Server"
},
"size": 2
}
}
{
"fields": {
"issuetype": {
"name": "Server"
},
"size": 2
}
}
{
"fields": {
"issuetype": {
"name": "Hardware"
},
"size": 0.58
}
}
The transformed data should be structered like this:
[
{
"item": "Hardware",
"size": 0.58
},
{
"item": "Server",
"size": 4
}
]
I am using the following code
jq -s < input.json "group_by( .fields.issuetype.name ) | .[] | item: .[0].fields.issuetype.name), size:([.[].fields.customfield_1234] | add)" > transformedData.json
Almost there. To construct objects, you need object contructors.
group_by(.fields.issuetype.name)
| map({item: .[0].fields.issuetype.name, size: map(.fields.size) | add})
Online demo

using jq how to query and replace value within an array

How do I query and replace the value for SMT_PORT_3306_TCP_ADDR.
I tried
echo $task_definition | jq -r '.taskDefinition.containerDefinitions[0].environment[] | select(.name=="SMT_PORT_3306_TCP_ADDR")| .value = "myvalue" '
the output I get
{
"name": "SMT_PORT_3306_TCP_ADDR",
"value": "myvalue"
}
I do not get the full json
Input Json :
{
"taskDefinition": {
"taskDefinitionArn": "some value",
"containerDefinitions": [
{
"name": "common-api-img",
"environment": [
{
"name": "SERVER_API_TIMEOUT_SUBSCRIPTIONS_CANCEL_REQUEST",
"value": "false"
},
{
"name": "SMT_PORT_3306_TCP_ADDR",
"value": "valueToReplace"
}
],
"mountPoints": [],
"volumesFrom": []
}
],
"revision": 65,
"volumes": [],
"status": "ACTIVE"
}
}
Expected output without the top level taskDefinition value:
{
"taskDefinitionArn":"some value",
"containerDefinitions":[
{
"name":"common-api-img",
"environment":[
{
"name":"SERVER_API_TIMEOUT_SUBSCRIPTIONS_CANCEL_REQUEST",
"value":"false"
},
{
"name":"SMT_PORT_3306_TCP_ADDR",
"value":"myvalue"
}
],
"mountPoints":[
],
"volumesFrom":[
]
}
],
"revision":65,
"volumes":[
],
"status":"ACTIVE"
}
Use |= with if.
jq '.taskDefinition.containerDefinitions[0].environment[]
|= if .name == "SMT_PORT_3306_TCP_ADDR"
then .value = "myvalue"
else .
end'

Mule 4 - How to combine arrays inside a nested array with the same id field into one

Suppose I have the following payload with nested array, how do I combine the array inside the nested array for the same externalId as well as some logic on certain field like
shipQty - this field will be sum or add up for records with the same externalId under fillingOrder
serialNumbers - all the records under serialNumbers will be display together if the externalId is same
Kindly refer below for the input and expected output
Json Payload Input
{
"Identifier": "9i098p-898j-67586k",
"transactionDate": "2019-09-08T10:01:00-04:00",
"order": [
{
"orderNumber": "123456789",
"CourierOrderId": "1300-88-2525",
"fillingOrder": [
{
"numberOfBoxes": 0,
"tracking": [
{
"carrier": "Orange",
"trackNum": "3333444",
"trackUrl": "https://www.orange.com/track/status",
"shipDate": "2019-09-08T10:01:00-04:00",
"SerialNumber": "00000123"
}
],
"row": [
{
"externalId": "1",
"unitNo": "OP04-123456-789",
"shipQty": 2,
"serialNumbers": [
{
"serialNumber": "USD333555",
"quantity": 1
},
{
"serialNumber": "USD235678",
"quantity": 1
}
]
}
]
},
{
"tracking": [
{
"carrier": "Apple",
"trackNum": "555666",
"trackUrl": "https://www.apple.com/track/status",
"shipDate": "2019-09-08T10:01:00-04:00",
"SerialNumber": "00000645"
}
],
"row": [
{
"externalId": "1",
"unitNo": "OP04-123456-789",
"shipQty": 3,
"serialNumbers": [
{
"serialNumber": "USD123456",
"quantity": 1
},
{
"serialNumber": "USD98765",
"quantity": 1
},
{
"serialNumber": "USD45689",
"quantity": 1
}
]
}
]
},
{
"tracking": [
{
"carrier": "banana",
"trackNum": "587390",
"trackUrl": "https://www.banana.com/track/status",
"shipDate": "2019-09-08T10:01:00-04:00",
"SerialNumber": "00000365"
}
],
"row": [
{
"externalId": "2",
"unitNo": "OP05-123456-111",
"shipQty": 2,
"serialNumbers": [
{
"serialNumber": "USD00045",
"quantity": 1
},
{
"serialNumber": "USD00046",
"quantity": 1
}
]
}
]
}
]
}
]
}
Expected Json Output
{
"row": [
{
"externalId": "1",
"unitNo": "OP04-123456-789",
"shipQty": 5, //the shipQty should be add up when the externalId is same
"serialNumbers": [ //the serialNumbers should display all the data inside the serialNumbers when the externalId is same
{
"serialNumber": "USD333555",
"quantity": 1
},
{
"serialNumber": "USD235678",
"quantity": 1
},
{
"serialNumber": "USD123456",
"quantity": 1
},
{
"serialNumber": "USD98765",
"quantity": 1
},
{
"serialNumber": "USD45689",
"quantity": 1
}
]
},
{
"externalId": "2",
"unitNo": "OP05-123456-111",
"shipQty": 2,
"serialNumbers": [
{
"serialNumber": "USD00045",
"quantity": 1
},
{
"serialNumber": "USD00046",
"quantity": 1
}
}
]
}
It looks like you only need the data of "row" inside the fillingOrder field of your payload. So first thing to simplicy the problem is to get all the rows as a single array. Once you have that them you just need to group that by external id and the problem will start to look smaller.
%dw 2.0
output application/json
//First get all rows since it looks like you only need them.
//If you find this confusing try to use flatten with some simpler payloads.
var allRows = flatten(flatten(payload.order.fillingOrder).row)
//Group them according to external id.
var groupedExtId = allRows groupBy $.externalId
---
{
row: groupedExtId pluck ((value, extId, index) -> do {
var sumShipQuant = sum(value.shipQty default [])
---
{
externalId: (extId), //the key after grouping is external id
unitNo: value.unitNo[0], //assuming it is same across diff external id
shipQty: sumShipQuant,
serialNumbers: flatten(value.serialNumbers) //Flatten because value is an array and it has multiple serielNumbers array
}
})
}
This should help. I took some inspiration from Harshank Bansal post
%dw 2.0
output application/json
var groupFlat = flatten(flatten (payload.order.fillingOrder).row) groupBy ($.externalId)
---
row: [groupFlat mapObject ((value, key, index) -> {
externalId: value.externalId[0],
unitNO: value.unitNo[0],
shipQty: sum(value.shipQty),
serialNumbers: flatten(value.serialNumbers)
})]
Try this:
%dw 2.0
output application/json
---
row:[ if (payload..order..row..externalId[0] == payload..order..row..externalId[1]) {
externalId : payload..order..row..externalId[0],
unitNo: payload..order..row..unitNo[0],
shipQty: payload..order..row..shipQty[0] + payload..order..row..shipQty[1],
serialNumbers: flatten (payload..order..row..serialNumbers)
}
else null]

Resources