格式化由 Invoke-RestMethod 或 ConvertFrom-JSON 返回的 [pscustomobjec



我正在尝试从从RESTful API接收的JSON文件创建一个表。

当我打印 json 对象的属性时,我得到这样的输出:

PS> 写入输出 JSON。对象 对象 1 : @{key1=property; key2=property; key3=property; key4=property} 对象 2 : @{key1=property; key2=property; key3=property; key4=property} 对象 3 : @{key1=property; key2=property; key3=property; key4=property} 对象4 : @{key1=property; key2=property; key3=property; key4=property}

我想看到的输出是这样的:

名称键1键2键3键4 -----             ----        ----        ----        ---- 对象 1 属性 对象 2 属性 属性 属性 属性 Object3 属性

此外,是否可以避免显示特定键及其属性?

例:

名称 key1 key2 key4# ← 不显示键 3----- ---- ---- ---- 对象 1 属性 对象 2 属性 对象 3 属性

您需要将父键名添加为嵌套对象的属性Name

$json.Object | ForEach-Object {
foreach ($p in $_.PSObject.Properties) {
$p.Value | Select-Object @{n='Name';e={$p.Name}},*
}
}

请注意,默认情况下,PowerShell 将以列表形式呈现输出,因为对象具有 4 个以上的属性。通过管道将其通过Format-List -AutoSize获取表格输出。

为了用背景信息补充Ansgar Wiecher的优雅回答:

让我们定义示例输入,该输入模拟通过ConvertFrom-Json转换为 PowerShell[pscustomobject]实例的单个嵌套对象:

$objFromJson = [pscustomobject] @{ 
Object1 = [pscustomobject] @{key1='o11'; key2='o12'; key3='o13'; key4='o14'}
Object2 = [pscustomobject] @{key1='o21'; key2='o22'; key3='o23'; key4='o24'} 
Object3 = [pscustomobject] @{key1='o31'; key2='o32'; key3='o33'; key4='o34'} 
Object4 = [pscustomobject] @{key1='o41'; key2='o42'; key3='o43'; key4='o44'} 
Object5 = [pscustomobject] @{key1='o51'; key2='o52'; key3='o53'; key4='o54'} 
}

输出$objFromJson给出的输出格式与问题中的格式相同。

为什么这会导致问题中显示的输出格式?

对于像[pscustomobject]这样的类型,它们没有为它们定义的显式格式定义(通过*.ps1xml文件并隐式加载到会话中或通过Update-FormatData显式加载),PowerShell 根据类型的属性数决定要使用的默认格式:

  • 最多具有 4 个属性的类型隐式使用Format-Table
  • 具有 5 个或更多属性的类型隐式使用Format-List

问题中的示例输入大概是删节的;实际上只有 4 个属性,会产生表格显示。

属性本身是通过对其值调用.PSObject.ToString()来呈现的,这通常与在双引号字符串中引用对象时得到的表示形式相同,只是后者始终使用区域性不变格式,而.ToString()将尊重当前区域性(如果类型支持)。

[pscustomobject]实例的情况下,这会导致类似于哈希表文本的表示形式,但不是(有关背景信息,请参阅此答案);例如:

PS> $objFromJson.Object1.PSObject.ToString()
@{key1=o11; key2=o12; key3=o13; key4=o14}

根据需要重塑数据:

无法直接使用格式化 cmdlet(如Format-Table)来生成所需的输出 - 必须先重塑数据:

具体而言,对象$objFromJson的属性必须重塑为自定义对象的集合

  • Name属性包含给定属性的名称,以及

  • 其其他属性是该属性值的对象的属性;换句话说:输入属性值的属性必须成为输出对象本身的属性。

PowerShell 向所有对象添加(其中包括)隐藏的.PSObject属性,这些对象自己的.Properties属性包含对象的所有属性定义(名称、值、附加元数据,如属性类型等)的集合;例如:$objFromJson

PS> $objFromJson.Object1.PSObject.Properties
MemberType      : NoteProperty
IsSettable      : True
IsGettable      : True
Value           : o11
TypeNameOfValue : System.String
Name            : key1
IsInstance      : True
# ... remaining properties

输出$objFromJson的属性定义的集合并仅提取定义的NameValue属性是朝着正确方向迈出的一步:

PS> $objFromJson.PSObject.Properties | Select-Object Name, Value
Name    Value                                    
----    -----                                    
Object1 @{key1=o11; key2=o12; key3=o13; key4=o14}
Object2 @{key1=o21; key2=o22; key3=o23; key4=o24}
Object3 @{key1=o31; key2=o32; key3=o33; key4=o34}
Object4 @{key1=o41; key2=o42; key3=o43; key4=o44}
Object5 @{key1=o51; key2=o52; key3=o53; key4=o54}

但是,我们必须使.Value属性的属性直接输出对象的属性,以获得具有属性单个值的输出。

Ansgar 优雅的回答演示了如何在单个管道中做到这一点。
让我用一个派生的可重用的帮助程序函数来补充它:

function ConvertTo-Collection($InputObject) {
foreach ($obj in $InputObject) {
foreach ($prop in $obj.PSObject.Properties) {
$prop.Value | Select-Object @{ n='Name'; e={ $prop.Name }}, *
}
} 
}

有了该功能,现在可以实现所需的输出:

ConvertTo-Collection $objFromJson | Format-Table

要排除特定属性,例如key3

ConvertTo-Collection $objFromJson | Select-Object -ExcludeProperty key3 |
Format-Table

相关内容

  • 没有找到相关文章

最新更新