PowerShell Invoke-RestMethod 在浏览数组值时跳过返回的空值.想法? [英] PowerShell Invoke-RestMethod skips a returned null value when navigating through the array values. Ideas?
问题描述
我正在调用一个 API,该 API 在对象tags"中返回 3 个值,该对象具有tags.name"的值.和标签.结果".下面的值是返回的值.但是当我尝试浏览这些值时,我可以看到null"值 {} 未存储在数组中.它只是跳过了它,但我需要这个值,因为它完全破坏了数组.
I am calling an API that returns 3 values in an object "tags", which has values for "tags.name" and tags.results". The values below are what is returned. But as I try to navigate through the values, I can see that the "null" value, the {}, was not stored in the array. It just skipped it, but I need this value as it completely ruins the array.
知道如何正确填充数组以使其不跳过此 {} 值吗?
Response Values
values attributes
------ ----------
{1605560351000 78.129448 3} @{machine_type=System.Object[]}
{}
{1605560354000 0 3} @{machine_type=System.Object[]}
Resulting Array
0 : 1605560351000 78.129448 3
1 : 1605560354000 0 3
2 :
PowerShell nvoke 和数组代码:
The PowerShell nvoke and array code:
$response = Invoke-RestMethod 'https://api' -Method 'POST' -Headers $headers -Body $body
"Response Values"
$response.tags.results
""
"Resulting Array"
"0 : " + $response.tags.results.values[0]
"1 : " + $response.tags.results.values[1]
"2 : " + $response.tags.results.values[2]
从 Invoke-RestAPI 返回的 JSON.您可以看到第二个节点的返回值为 null 的位置.
The returned JSON from Invoke-RestAPI. You can see where the returned value is null for the second node.
{
"tags": [
{
"name": "StateComp1",
"results": [
{
"values": [
[
1605561152000,
75.436455,
3
]
],
}
],
},
{
"name": "StateComp2",
"results": [
{
"values": [],
}
],
},
{
"name": "StateComp3",
"results": [
{
"values": [
[
1605561469000,
0,
3
]
],
}
],
}
]
}
推荐答案
问题并非特定于 Invoke-RestMethod
而是由 PowerShell 成员枚举功能:
The problem is not specific to Invoke-RestMethod
and is instead explained by the behavior of PowerShell's member enumeration feature:
当您访问 $response.tags.results.values
时,.values
属性位于 - 多个 - .results
属性(您'正在使用 嵌套 成员枚举)有效地枚举如下:
When you access $response.tags.results.values
, the .values
properties on the - multiple - .results
properties (you're using nested member enumeration) are effectively enumerated as follows:
$response.tags.results | ForEach-Object { $_.values }
这样做,空数组被有效地从输出中移除,而你只得到2个输出对象(在您的情况下,每个对象都包含嵌套对象的 inner 数组);您可以通过将 (...).Count
应用于上面的命令来验证这一点.
In doing so, empty arrays are effectively removed from the output, and you get only 2 output objects (that each contain the inner array of the nested ones in your case); you can verify that by applying (...).Count
to the command above.
原因是 script block ({ ... }
) 被发送到 pipeline,默认情况下,它枚举 对象是集合(数组).
由于 您的第二个 .values
值是一个 空 数组(从 JSON []
解析,因此 不是 $null
),没有什么可枚举,没有输出,从而有效去除.
The reason is that objects output by a script block ({ ... }
) are sent to the pipeline, which by default enumerates objects that are collections (arrays).
Since your 2nd .values
value is an empty array (parsed from JSON []
and therefore not $null
), there is nothing to enumerate and nothing is output, resulting in effective removal.
请注意,以上意味着集合的集合被成员枚举扁平化;例如,如果属性值为 3 个 2 元素数组,则管道枚举逻辑会生成单个 6 元素数组,而不是每个包含 2 元素数组的 3 元素数组.
Note that the above implies that collections of collections are flattened by member enumeration; for instance, if the property values are 3 2-element arrays, the pipeline-enumeration logic results in a single 6-element array rather than in a 3-element array containing 2-element arrays each.
解决方法是使用 ForEach()
数组方法,它不会执行此剥离如果您针对该属性通过将其名称作为 string 提供:
The workaround is to to use the ForEach()
array method, which doesn't perform this stripping if you target the property by supplying its name as a string:
$values = $response.tags.results.ForEach('values')
@"
Resulting Array"
0 : $($values[0])
1 : $($values[1])
2 : $($values[2])
"@
请注意,您的非空 .values
属性实际上是 嵌套 数组;要去掉外部数组,请使用 $values[0][0]
、$values[1][0]
和 $values[2][0]]
.
Note that your non-empty .values
properties are actually nested arrays; to shed the outer array, use $values[0][0]
, $values[1][0]
, and $values[2][0]
.
警告:只有当您按名称访问属性字符串 - .ForEach('values') 时,该解决方法才有效代码>;看似等效的基于脚本块的命令,
.ForEach({ $_.values })
再次删除空数组,如成员枚举和 ForEach-Object
cmdlet;或者,但是,您可以通过将脚本块输出包装在一个辅助的、临时的单元素数组中来解决这个问题,该数组保留了原始数组,使用一元形式的,
数组构造器运算符:.ForEach({ , $_.values })
您也可以使用相同的技术 - 慢 - ForEach-Object
cmdlet.
Caveat: The workaround is only effective if you access the property by name string - .ForEach('values')
; the seemingly equivalent script-block based command,
.ForEach({ $_.values })
again removes empty arrays, like member enumeration and the ForEach-Object
cmdlet; alternatively, however, you can work around that by wrapping the script-block output in an auxiliary, temporary single-element array that preserves the original arrays, using the unary form of ,
the array constructor operator:
.ForEach({ , $_.values })
You could also use the same technique with the - slower - ForEach-Object
cmdlet.
这篇关于PowerShell Invoke-RestMethod 在浏览数组值时跳过返回的空值.想法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!