Tae*_*ous 1 powershell json cmdlet
我成功地向我的 JSON 添加了一个成员,但我最终得到了不需要的元素。我要添加的是出现在结果 JSON 中的“Value”中的元素。
{
"Block1": value1,
"Block2": value2,
"Block3": []
}
Run Code Online (Sandbox Code Playgroud)
然后执行 Add-Member cmdlet。
$objectFromJson |
Add-Member -NotePropertyName "Block3" -NotePropertyValue $newblock -Force
Run Code Online (Sandbox Code Playgroud)
我意识到我不必执行-Force部分,但在我的工作代码中,我的 JSON 字符串使用ConvertFrom-Json解析为一个对象,并且该部分对我的目的有效。
存储在数组中有 1 到 N 个元素$newblock,要序列化为数组值属性Block3。
不幸的是,我最终得到以下结果:
{
"Block1": value1,
"Block2": value2,
"Block3": [ { "value": { <elements of $newblock> }, "Count": <n> } ]
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码片段中,<elements of $newblock>表示$newblock数组元素的 JSON 表示,以及数组中元素<n>的数量。
它是有效的 JSON,但不是我想要的。相反,我希望 的元素是数组的$newblock直接元素Block3,而没有带有value和Count属性的无关包装器对象:
{
"Block1": value1,
"Block2": value2,
"Block3": [ <elements of $newblock> ]
}
Run Code Online (Sandbox Code Playgroud)
tl;博士
您自己的解决方案避免了原始问题,并且可以说是更好的开始方法:通过原始 JSON(而不是稍后通过)将.Block3属性创建为数组,然后使用 将元素添加到该数组中。Add-Member+=
但是,您可以通过简单地(但模糊地)传递-NotePropertyValue $newblock.psobject.BaseObject而不是 来解决原始问题-NotePropertyValue $newblock,这会删除导致问题[psobject]的数组周围的不可见包装$newblock。请继续阅读以获取解释。
最后重要的是:存储在属性中的数组不能有一个不可见的wrapper.Block3[psobject],因为在Windows PowerShell 中,这会导致数组序列化为 JSON 包装在一个带有和properties的额外对象中"Count""values"。
额外的对象源于.Count为数组命名的过时 ETS(扩展类型系统)属性的存在,该属性对[psobject]-wrapped 数组生效-有关详细信息,请参阅此答案。
该问题不再出现在 PowerShell [Core] v6+ 中,因为此 ETS 属性已在那里删除。
Add-Member 是错误的方法,因为它在幕后添加了 PSObject 或 PSCustomObject。
实际上,Add-Member它本身并没有这样做,因为-NotePropertyValue参数是[object]-typed,而不是[psobject]-typed。
存储在您的$newblock变量中的数组必须已经被[psobject]包装:
$newblock -is [psobject]可能$true为您指示,而常规数组则没有(例如,1, 2 -is [psobject]is $false)
例如,从 cmdlet返回的数组,作为一个整体将有一个不可见的[psobject]包装器,特别是当您使用New-Objectcmdlet 时:(New-Object string[] 2) -is [psobject]返回$true
有关添加此不可见额外包装器的所有场景,请参阅此 GitHub 问题[psobject],这也可能导致其他细微的行为差异,这些差异仍会影响 v7.0 中的 PowerShell [Core](但是,如上所述,此特定问题已得到修复通过删除 ETS 属性)。
有两种一般的解决方法:
会话范围:
ConvertTo-Json,运行以下命令,删除过时的 ETS 属性,之后数组按预期序列化 - 无论是否[psobject]-wrapped:Remove-TypeData System.Array对于给定的数组变量:
.psobject.BaseObject访问数组的展开,基础.NET阵列; 在你的情况下:$newblock.psobject.BaseObject例子:
会话范围的解决方法:
# The problem: Serialize a [psobject]-wrapped array (0, 0):
PS> ConvertTo-Json -InputObject (New-Object int[] 2)
# Note the extra object with the "count" (element count) and "value" property (elements)
{
"value": [
0,
0
],
"Count": 2
}
# Remove the ETS definitions for System.Array
Remove-TypeData System.Array
# Rerun the command:
PS> ConvertTo-Json -InputObject (New-Object int[] 2)
# OK
[
0,
0
]
Run Code Online (Sandbox Code Playgroud)
给定数组变量的解决方法:
PS> $arr = New-Object int[] 2; ConvertTo-Json -InputObject $arr
# Note the extra object with the "count" (element count) and "value" property (elements)
{
"value": [
0,
0
],
"Count": 2
}
# $arr.psobject.BaseObject bypasses the [psobject] wrapper
PS> ConvertTo-Json -InputObject $arr.psobject.BaseObject
# OK
[
0,
0
]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1561 次 |
| 最近记录: |