观察:
C:\> [array]@(1,2) | ConvertTo-Json
[
1,
2
]
C:\> [array]@(1) | ConvertTo-Json
1
C:\> [array]@() | ConvertTo-Json
C:\>
(我希望从最后两个案例中分别得到 [1] 和 [])
所以,如果我想使用标准
ConvertTo-Json
方法,我如何可靠地做到这一点,即使数组包含 1 或 0 个元素?请注意,当数组是转换为 json 的复杂对象的一部分时,对结果进行后处理是不可行的。
编辑 1
C:\> $PSVersionTable
Name Value
---- -----
PSVersion 5.1.17763.592
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.17763.592
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
C:\> [array]@(1) | ConvertTo-Json -AsArray
ConvertTo-Json : A parameter cannot be found that matches parameter name 'AsArray'.
At line:1 char:30
+ [array]@(1) | ConvertTo-Json -AsArray
+ ~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [ConvertTo-Json], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.ConvertToJsonCommand
C:\>
最佳答案
PowerShell Core (v6+) 提供方便的 -AsArray
开关,在底部讨论。
如果 $val
是空数组、标量或数组 发送, @($val)
至ConvertTo-Json
通过管道确保它被序列化为数组:
if (-not $IsCoreCLR) { # Workaround for Windows PowerShell
# Only needed once per session.
Remove-TypeData -ErrorAction Ignore System.Array
}
# Send an empty array, a single object, and an array...
@(), 1, (1, 2) | ForEach-Object {
# ... and ensure that each input ($_) serializes as a JSON *array*.
, @($_) | ConvertTo-Json
}
笔记:
,
, 数组构造运算符 , 在这里以一元形式使用,以提供辅助的单元素包装数组,以便 发送整个数组 (作为单个对象)通过管道; 默认情况下,将数组(可枚举)发送到管道会一一发送其元素 ;请注意,这是基本的管道行为,与涉及的 cmdlet 无关。 @(...)
,“数组保证”运算符(数组子表达式运算符),确保 $_
是一个数组 ,也就是说,它将操作数包装在一个数组中,除非它已经是一个(松散地说[1]);这对于涵盖 $_
的情况是必要的仅包含一个对象(标量;在本例中为 1
)。 ConvertTo-Json
悄悄地将其序列化深度限制为 2
默认 , 其中 使用更深的嵌套输入导致安静的数据丢失 ;使用 -Depth
参数根据需要。以上产生以下结果 - 请注意每个输入如何序列化为数组:
[]
[
1
]
[
1,
2
]
或者,您可以将输入作为参数传递给
ConvertTo-Json
与 @($val)
:# Same output as above.
@(), 1, (1,2) | ForEach-Object { ConvertTo-Json @($_) }
位置参数隐式绑定(bind)到
-InputObject
参数,它不枚举其参数,因此按原样绑定(bind)数组。因此您只需要“数组保证人”
@()
在这种情况下(也不是带有 ,
的包装器数组)。PowerShell Core 现在提供
-AsArray
开关 ,它直接确保输入被序列化为一个数组,即使只有一个输入对象:PS> 1 | ConvertTo-Json -AsArray
[
1
]
但是,鉴于空数组导致没有数据通过管道发送,您 如果输入是空数组,仍然需要一个包装器数组,然后你不能使用
-AsArray
:# Note:
# @() | ConvertTo-Json -AsArray
# would result in NO output.
# Use `, ` to wrap the empty array to ensure it gets sent through
# the pipeline and do NOT use -AsArray
PS> , @() | ConvertTo-Json -Compress
[]
或者,再次将空数组作为参数传递:
PS> ConvertTo-Json @() -Compress # Do NOT use -AsArray
[]
问题是
-AsArray
无条件地将其输入包装在 JSON 数组中 ,以便再次包装已经是数组的东西:PS> ConvertTo-Json -AsArray @() -Compress
[[]] # *nested* empty arrays
那
-AsArray
不像 @(...)
那样充当数组“担保人”确实在 this GitHub issue 中进行了讨论.[1] 如果操作数是标量(单个对象),则将其包裹在单个元素中
[object[]]
;如果操作数已经是一个数组或者是一个可枚举的,这些元素被枚举并捕获在一个新的[object[]]
中。大批。
关于json - 如何使用 ConvertTo-Json 将 powershell 数组转换为 json?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58617070/