Powershell附加成员-但不包含“值"和“计数" JSON中的元素 [英] Powershell Add-Member - But without "Value" and "Count" elements in JSON
问题描述
我已成功将成员添加到JSON,但最终得到不需要的元素.我要添加的是出现在结果JSON中的值"中的元素.
I am successfully adding a member to my JSON, but I end up with unwanted elements. What I am trying to add is the element inside "Value" that is appearing in the resulting JSON.
{
"Block1": value1,
"Block2": value2,
"Block3": []
}
然后执行Add-Member cmdlet.
Then doing the Add-Member cmdlet.
$objectFromJson |
Add-Member -NotePropertyName "Block3" -NotePropertyValue $newblock -Force
我意识到我不必做 -Force 部分,但是在我的工作代码中,我的JSON字符串使用 ConvertFrom-Json 解析为一个对象,并且对我而言,这部分有效.
I realize I do not have to do the -Force part, but in my working code, my JSON string is parsed to an object using ConvertFrom-Json and that part is effective for my purposes.
$newblock
中存储的数组中有1到N个元素,要序列化为数组值属性Block3
.
There are from 1 to N elements in the array stored in $newblock
, to be serialized as array-valued property Block3
.
不幸的是,我得到以下结果:
Unfortunately, I end up with the following:
{
"Block1": value1,
"Block2": value2,
"Block3": [ { "value": { <elements of $newblock> }, "Count": <n> } ]
}
在上面的代码段中,<elements of $newblock>
表示$newblock
数组元素的JSON表示形式,以及<n>
数组中元素的计数.
In the snippet above, <elements of $newblock>
represent the JSON representation of the $newblock
array elements, and <n>
the count of elements in the array.
这是有效的JSON,但不是我想要的.相反,我希望$newblock
的元素是Block3
数组的直接元素,而没有带有value
和Count
属性的无关包装对象:
It is valid JSON, but not what I desire. Instead, I want the elements of $newblock
to be direct elements of the Block3
array, without the extraneous wrapper object with the value
and Count
properties:
{
"Block1": value1,
"Block2": value2,
"Block3": [ <elements of $newblock> ]
}
推荐答案
tl; dr
-
您自己的解决方案避免了原始问题,并且可以说是更好的入门方法:通过原始JSON (而不是稍后通过
Add-Member
)将.Block3
属性作为数组(而不是稍后通过Add-Member
),并在以后使用+=
将元素添加到该数组中.
Your own solution avoids the original problem, and is arguably the better approach to begin with: Create the
.Block3
property as an array via the original JSON (rather than later viaAdd-Member
), and add elements to that array later with+=
.
但是,您可以通过简单地(但晦涩地)传递
-NotePropertyValue $newblock.psobject.BaseObject
而不是
-NotePropertyValue $newblock
来解决原始问题,这将删除存储在数组周围的不可见的[psobject]
包装器导致问题的$newblock
.继续阅读以获取解释.
However, you could have fixed the original problem by simply (but obscurely) passing -NotePropertyValue $newblock.psobject.BaseObject
instead of -NotePropertyValue $newblock
, which removes the invisible [psobject]
wrapper around the array stored in $newblock
that caused the problem. Read on for an explanation.
最后重要的是:存储在.Block3
属性中的 array 一定没有不可见的[psobject]
包装器 ,因为 Windows PowerShell 中的会导致数组序列化为包含在具有"Count"
和"values"
属性的额外对象中的JSON.
What matters in the end is: the array stored in the .Block3
property must not have an invisible [psobject]
wrapper, because in Windows PowerShell that causes the array to serialize to JSON wrapped in an extra object with "Count"
and "values"
properties.
额外的对象源于数组的名为.Count
的过时ETS(扩展类型系统)属性的存在,该属性对[psobject]
封装的数组生效-请参见
The extra object stem from the presence of an obsolete ETS (extended-type system) property named .Count
for arrays, which takes effect for [psobject]
-wrapped arrays - see this answer for the gory details.
此问题不再在PowerShell [Core] v6 + 中出现,因为此ETS属性已在此处删除.
The problem no longer surfaces in PowerShell [Core] v6+, because this ETS property has been removed there.
添加成员是错误的方法,因为它在幕后添加了PSObject或PSCustomObject.
Add-Member was the wrong approach, since it adds a PSObject or PSCustomObject under the covers.
实际上,Add-Member
本身不会执行 的操作,因为-NotePropertyValue
参数是[object]
类型的,而不是[psobject]
类型的.
Actually, Add-Member
by itself does not do that, because the -NotePropertyValue
parameter is [object]
-typed, not [psobject]
-typed.
存储在$newblock
变量中的数组必须已经被[psobject]
包装:
$newblock -is [psobject]
可能为您指示$true
,而常规数组则不会(例如1, 2 -is [psobject]
是$false
)
The array stored in your $newblock
variable must already have been [psobject]
wrapped:
$newblock -is [psobject]
probably indicates $true
for you, whereas a regular array does not (e.g., 1, 2 -is [psobject]
is $false
)
例如,从整个cmdlet返回的数组将具有不可见的[psobject]
包装器,特别是当您使用New-Object
cmdlet时:
(New-Object string[] 2) -is [psobject]
返回$true
For instance, an array returned from a cmdlet, as a whole will have an invisible [psobject]
wrapper, notably when you use the New-Object
cmdlet: (New-Object string[] 2) -is [psobject]
returns $true
请参见此GitHub问题,以了解所有这种看不见的额外内容[psobject]
的情况.添加了包装程序,这也可能导致其他细微的行为差异,这些差异仍会影响v7.0或更高版本的PowerShell [Core](但如上所述,此特定问题已通过删除ETS属性).
See this GitHub issue for all scenarios in which this invisible extra [psobject]
wrapper is added, which can cause other subtle behavioral differences as well, which still affect PowerShell [Core] as of v7.0 (but, as stated, this particular issue has been fixed by the removal of the ETS property).
有两种一般解决方法:
-
整个会话:
- 在调用
ConvertTo-Json
之前,运行以下命令,该命令将删除过时的ETS属性,此后,数组将按预期的顺序进行序列化-是否包装[psobject]
:
Remove-TypeData System.Array
- Before calling
ConvertTo-Json
, run the following command, which removes the obsolete ETS property, after which arrays serialize as expected - whether[psobject]
-wrapped or not:
Remove-TypeData System.Array
对于给定的数组变量:
- 使用
.psobject.BaseObject
访问数组的未包装基础.NET数组;您的情况:$newblock.psobject.BaseObject
- Use
.psobject.BaseObject
to access the array's unwrapped, underlying .NET array; in your case:$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
]
给定数组变量的解决方法:
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
]
这篇关于Powershell附加成员-但不包含“值"和“计数" JSON中的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!