如果不是数组 powershell,则将 JSON 属性 更改为数组

Change JSON property to an array if not an array powershell

我有一个 JSON 我想检查它是否是一个数组,如果不是,我想更新 JSON 并将其更改为数组

{
    "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

到目前为止的代码

$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

我希望地址是一个数组。我可以在 powershell 中这样做吗?

使用ForEach-Object and reassign the address property value by enclosing it in @(...), the array-subexpression operator,确保它是一个数组(如果它已经一个数组,没有任何变化[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

注意赋值后的 stand-alone $_ 语句:它确保(修改后的)输入对象也是 output (到下一个管道段),使用 PowerShell 的 隐式输出功能 - 参见 .

: 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 .[2]

上面的结果如下,表明 address 属性 现在是一个数组:

{
  "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] 从技术上讲,创建了现有数组的(浅)副本,但这在这里没有任何区别。
要了解有关 @() 运算符的更多信息,请参阅

[2] 这个要求很繁琐,容易遗漏,但是为了向后兼容没有改变。但是,PowerShell 7.1 版至少会在(可能是默认的)-Depth 值不足时发出 警告:请参阅 this PR and the associated discussion in GitHub issue #8393.
此外,在将 JSON cmdlet 的实现从 Newtonsoft.Json 库移动到新的(ish)built-in System.Text.Json API,在 v7.1 之后的某个时候,这将不可避免地带来重大更改 - 请参阅 this PR