0

I have two different JSONs and I would like to remove streets from the JSON object if only it exists under Address which is an array. I am trying to do this in powershell. I can get my script working and remove the streets but I only want to run the exclude line of command if the address has the streets property.

{
    "Customer": [{
        "id": "123"
    }],
    "address": [{
            "$type": "Home",
            "name": "Houston",
            "streets": [{
                "name": "Union",
                "postalCode": "10"
            }]
        },
        {
            "$type": "Office",
            "name": "Hawai",
            "streets": [{
                "name": "Rock",
                "postalCode": "11"
            }]
        }
    ]
}

2nd JSON - Do not want to run the exclude line for 2nd JSON because there are no streets

{
    "Customer": [{
        "id": "123"
    }],
    "address": [{
            "$type": "Home",
            "name": "Houston"
        },
        {
            "$type": "Office",
            "name": "Hawai"
        }
    ]
}

Powershell script

$FileContent = Get-Content -Path "Test.json" -Raw | ConvertFrom-Json
#Only want to run for address objects that contains streets
$FileContent.address = $FileContent.address | Select-Object * -ExcludeProperty streets #Only run for 1st json and not for 2nd json
$FileContent | ConvertTo-Json

0

2 Answers 2

2

If you want to execute the code only if the address has the member streets you can test for just that:

if (
    ($FileContent.address | Get-Member -MemberType NoteProperty -Name "streets") -ne $null
){
    $FileContent.address = $FileContent.address | Select-Object * -ExcludeProperty streets
}
Sign up to request clarification or add additional context in comments.

Comments

2

T-Me's helpful answer is the most robust approach, because it looks for the presence of the property itself rather than non-null values.

If you're willing to assume that the absence of a value also means the absence of the property itself, you can take the following shortcut, which performs better:

$hasAtLeastOneStreet = 0 -ne
 (@((Get-Content Test.json -Raw | ConvertFrom-Json).address.streets) -ne $null).Count

.address.streets uses member-access enumeration to extract all streets values, @(...) ensures that the result is an array, -ne $null filters out any $null values from that array, and .Count counts its elements.

Note: This expression should be simpler:
$null -ne (Get-Content Test.json -Raw | ConvertFrom-Json).address.streets
but due to a bug currently cannot - see the bottom section.

To demonstrate (the input strings are compressed, single-line versions of your JSON documents):

'{"Customer":[{"id":"123"}],"address":[{"$type":"Home","name":"Houston","streets":[{"name":"Union","postalCode":"10"}]},{"$type":"Office","name":"Hawai","streets":[{"name":"Rock","postalCode":"11"}]}]}',
'{"Customer":[{"id":"123"}],"address":[{"$type":"Home","name":"Houston"},{"$type":"Office","name":"Hawai"}]}' | 
  foreach { 
    "has street values: " + 
      (0 -ne @(((ConvertFrom-Json $_).address.streets) -ne $null).Count)
  }

The above yields, showing that the first JSON document had street values, whereas the second one did not.

has street values: True
has street values: False

Note: You should be able to simplify the test expression to the following, but this doesn't work due to a bug present up to at least PowerShell 7.3.4:

# !! SHOULD work, but as of PowerShell 7.3.4 DOESN'T, due to a bug 
# !! in how [pscustomobject]s are treated in member-access enumeration.
$null -ne (Get-Content Test.json -Raw | ConvertFrom-Json).address.streets

Normally, the absence of any streets property values should result in $null, but with two or more [pscustomobject] instances present in the .address array, an array of $null values is unexpectedly returned.

See GitHub issue #13752.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.