PowerShell Invoke-RestMethod 在浏览数组值时跳过返回的空值.想法? [英] PowerShell Invoke-RestMethod skips a returned null value when navigating through the array values. Ideas?

查看:31
本文介绍了PowerShell Invoke-RestMethod 在浏览数组值时跳过返回的空值.想法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在调用一个 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屋!

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