0

I have a JSON that I want to check if it is an array, if not, I want to update the JSON and change it to an array

{
    "Customer": [{
        "id": "123"
    }],
 "address": {
    "type": "home",
    "name": "what",
    "description": "",
    "adi:water": {
      "type": "comp",
      "location": "grass"
    },
    "att": [
      {
        "name": "cat",
        "type": "int"
      },
      {
        "name": "ds",
        "type": "string"
      }
    ]
  }
}

#For example address is not an array, I want to change so address is an array of one single object

Code so far

$File = ((Get-Content -Encoding UTF8 -path Test.json -Raw)

$File = $File| ConvertFrom-Json
$File.address = $File.address | Select-Object * -ExcludeProperty streets #This line changes it to an object instead of an array

I want the address to be an array. Can I do that in powershell?

1 Answer 1

1

Use ForEach-Object and reassign the address property value by enclosing it in @(...), the array-subexpression operator, to ensure that it is an array (if it already is an array, nothing changes[1]):

@'
{
  "Customer": [
      {
          "id": "123"
      }
  ],
  "address": {
      "type": "home",
      "name": "what",
      "description": "",
      "adi:water": {
          "type": "comp",
          "location": "grass"
      },
      "att": [
          {
              "name": "cat",
              "type": "int"
          },
          {
              "name": "ds",
              "type": "string"
          }
      ]
  }
}
'@ | ConvertFrom-Json | 
  ForEach-Object { 
    $_.address = @($_.address | Select-Object * -ExcludeProperty streets)
    $_ 
  } |
    ConvertTo-Json -Depth 4

Note the stand-alone $_ statement after the assignment: it ensures that (modified) input object is also output (to the next pipeline segment), using PowerShell's implicit output feature - see this answer.

Note: ConvertTo-Json limits the serialization depth to 2 by default, hence -Depth 4 was used above to prevent data loss. In general, keep in mind that you may have to pass a -Depth argument to ConvertTo-Json prevent data loss - see this post.[2]

The above yields the following, showing that the address property is now an array:

{
  "Customer": [
    {
      "id": "123"
    }
  ],
  "address": [
    {
      "type": "home",
      "name": "what",
      "description": "",
      "adi:water": {
        "type": "comp",
        "location": "grass"
      },
      "att": [
        {
          "name": "cat",
          "type": "int"
        },
        {
          "name": "ds",
          "type": "string"
        }
      ]
    }
  ]
}

[1] Technically, a (shallow) copy of an existing array is created, but that doesn't make any difference here.
To learn more about the @() operator, see this answer.

[2] This requirement is cumbersome and easy to miss, but hasn't been changed for the sake of backward compatibility. However, PowerShell version 7.1 will at least emit a warning when the (possibly default) -Depth value is insufficient: see this PR and the associated discussion in GitHub issue #8393.
Also, the issue may be revisited in the context of moving the implementation of the JSON cmdlets from the Newtonsoft.Json library to the new(ish) built-in System.Text.Json API, at some point after v7.1, which will inevitably entail breaking changes - see this PR.

Sign up to request clarification or add additional context in comments.

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.