如何使用ConvertTo-Json将Powershell数组转换为json? [英] How to convert powershell array to json using ConvertTo-Json?

查看:148
本文介绍了如何使用ConvertTo-Json将Powershell数组转换为json?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

观察:

C:\> [array]@(1,2) | ConvertTo-Json
[
    1,
    2
]
C:\> [array]@(1) | ConvertTo-Json
1
C:\> [array]@() | ConvertTo-Json
C:\>

(我希望最近两种情况分别是[1]和[])

(I expect [1] and [] from the last two cases respectively)

因此,如果我想使用标准的ConvertTo-Json方法,即使数组包含1或0个元素,我如何可靠地做到这一点?

So, if I want to use the standard ConvertTo-Json method, how do I do it reliably, even when the array contains 1 or 0 elements?

请注意,当数组是转换为json的复杂对象的一部分时,对结果进行后处理是不可行的.

Note, that post-processing the result is not feasible when the array is part of a complex object converted to 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开关,在底部讨论.

PowerShell Core (v6+) offers the convenient -AsArray switch, discussed in the bottom section.

如果$val是空数组,标量或数组,请通过管道将, @($val)发送到ConvertTo-Json ,以确保获取序列化为 array :

If $val is either the empty array, a scalar, or an array, send , @($val) to ConvertTo-Json via the pipeline to ensure that it gets serialized as an array:

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 
}

注意:

  • 此答案中说明了Windows PowerShell解决方法的需要.

  • The need for the Windows PowerShell workaround is explained in this answer.

, array-construction 运算符,此处以一元形式用于提供辅助的单元素包装器 wrapper 数组,以便通过管道将数组作为一个整体 发送(作为单个对象); 默认情况下,将一个数组(可枚举)发送到管道将其元素一个一个 发送;请注意,这是基本管道行为,与所涉及的cmdlet无关.

,, the array-construction operator, is used here in its unary form to provide an auxiliary, single-element wrapper array in order to send the array as a whole (as a single object) through the pipeline; by default, sending an array (enumerable) to the pipeline sends its elements one by one; note that this is fundamental pipeline behavior, irrespective of the cmdlets involved.

@(...)数组担保人" 运算符(数组子表达式运算符),确保 $_ array ,也就是说,它将操作数包装在一个数组中,除非它已经是一个了(松散地说 [1] );这对于覆盖仅包含单个对象(标量;在这种情况下为1)的$_情况是必要的.

@(...), the "array-guarantor" operator (array-subexpression operator), ensures that $_ is an array, that is, it wraps the operand in an array, unless it already is one (loosely speaking[1]); this is necessary to cover the case of $_ containing only a single object (scalar; 1 in this case).

一般警告: ConvertTo-Json默认将其序列化深度限制为2 ,这导致安静的数据丢失,并产生更多深度嵌套的输入;根据需要使用-Depth参数.

A general caveat: ConvertTo-Json quietly limits its serialization depth to 2 by default, which results in quiet data loss with more deeply nested input; use the -Depth parameter as needed.

此相关的GiHub问题要求将危险的默认行为设为已更改-如果您同意,请在此处听到您的声音.

This related GiHub issue asks for the treacherous default behavior to be changed - make your voice heard there, if you agree.

上面的代码产生了以下内容-请注意如何将每个输入序列化为数组:

The above yields the following - note how each input was serialized as an array:

[]
[
  1
]
[
  1,
  2
]

或者,您可以将输入作为自变量传递给ConvertTo-Json@($val) :

Alternatively, you can pass the inputs as arguments to ConvertTo-Json with @($val):

# Same output as above.
@(), 1, (1,2) | ForEach-Object { ConvertTo-Json @($_) }

位置参数隐式绑定到-InputObject参数,不枚举其参数,因此按原样绑定数组. 因此,在这种情况下,您仅需要数组担保人" @()(也不需要使用的包装器数组).

A positional argument implicitly binds to the -InputObject parameter, which does not enumerate its argument and therefore binds arrays as-is. Therefore you only need the "array guarantor" @() in this case (not also a wrapper array with ).

PowerShell Core 现在提供了一个-AsArray开关,即使只有一个单个,它也可以直接确保将输入序列化为数组. em>输入对象:

PowerShell Core now offers an -AsArray switch, which directly ensures that the input is serialized as an array, even if there's only a single input object:

PS> 1 | ConvertTo-Json -AsArray
[
  1
]

但是,鉴于空数组导致没有 no 数据通过管道发送,如果输入是 empty数组,则您仍然需要包装器数组,并且然后,您不必使用-AsArray :

However, given that empty arrays result in no data being sent through the pipeline, you still need a wrapper array if the input is the empty array and you then mustn't use -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

[]

或者,再次将空数组作为参数传递:

Alternatively, again pass the empty array as an argument:

PS> ConvertTo-Json @() -Compress # Do NOT use -AsArray

[]

问题在于, -AsArray 无条件将其输入包装在JSON数组中,以便将已经是数组的内容再次包装 :

The problem is that -AsArray unconditionally wraps its input in a JSON array, so that something that already is an array is wrapped again:

PS> ConvertTo-Json -AsArray @() -Compress

[[]]  # *nested* empty arrays

[1]如果操作数是标量(单个对象),则将其包装在单元素[object[]]中;否则,将其包装在单个元素中.如果操作数已经是数组或可枚举,则将元素枚举并捕获到 new [object[]]数组中.

[1] If the operand is a scalar (single object), it is wrapped in a single-element [object[]]; if the operand already is an array or is an enumerable, the elements are enumerated and captured in a new [object[]] array.

这篇关于如何使用ConvertTo-Json将Powershell数组转换为json?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆