格式化 Invoke-RestMethod 或 ConvertFrom-Json 返回的 [pscustomobject] 实例
Format [pscustomobject] instances returned by Invoke-RestMethod or ConvertFrom-Json
我正在尝试从 JSON 文件创建一个 table 我从 RESTful API.
收到
当我打印 json 对象的 属性 时,我得到如下输出:
PS> 写入输出 JSON.Object
对象 1:@{key1=属性;键2=属性;键3=属性; key4=属性}
对象 2:@{key1=属性;键2=属性;键3=属性; key4=属性}
对象 3:@{key1=属性;键2=属性;键3=属性; key4=属性}
对象 4:@{key1=属性;键2=属性;键3=属性; key4=属性}
我想看到的输出是这样的:
名称key1 key2 key3 key4
----- ----- ----- ---- ----
对象 1 属性 属性 属性 属性
Object2 属性 属性 属性 属性
Object3 属性 属性 属性 属性
此外,是否可以避免显示特定键及其属性?
示例:
Name key1 key2 key4 # ← 不显示key3
----- ----- ----- ----
对象 1 属性 属性 属性
对象 2 属性 属性 属性
Object3 属性 属性 属性
您需要将父键名作为 属性 Name
添加到嵌套对象中:
$json.Object | ForEach-Object {
foreach ($p in $_.PSObject.Properties) {
$p.Value | Select-Object @{n='Name';e={$p.Name}},*
}
}
请注意,默认情况下 PowerShell 将以列表形式呈现输出,因为您的对象具有 4 个以上的属性。通过 Format-List -AutoSize
进行管道传输以获得表格输出。
用背景信息补充 :
让我们定义模拟单个嵌套对象的示例输入,该对象通过 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]
这样的类型, 而 具有 explicit formatting definitions defined for them (via *.ps1xml
files and loaded implicitly into the session or explicitly via Update-FormatData
),PowerShell 根据 属性数量 类型:
- 具有最多 4 个属性的类型隐式使用
Format-Table
- 具有 5 个或更多属性的类型隐式使用
Format-List
问题中的样本输入大概是删节;真正只有 4 个属性时,会产生 表格 显示。
属性本身 是通过调用 .PSObject.ToString()
对其值进行渲染的,这通常与您希望的表示相同如果您在双引号字符串中引用对象,则获取,除了后者始终使用 culture-invariant 格式,而 .ToString()
将尊重当前文化,如果类型支持它。
在 [pscustomobject]
实例的情况下,这会导致 类似于 哈希表文字的表示,但不是一个(有关背景信息,请参阅 this answer);例如:
PS> $objFromJson.Object1.PSObject.ToString()
@{key1=o11; key2=o12; key3=o13; key4=o14}
根据需要重塑数据:
无法直接使用 Format-Table
等格式化 cmdlet 来产生所需的输出 - 数据必须 重塑 第一:
具体来说,对象 $objFromJson
的属性必须重塑为 自定义对象的集合 :
其 Name
属性 包含给定 属性 的 name 和
其其他属性是那个属性的值对象的属性;换句话说:输入 属性 的 value 的属性必须成为输出对象本身的属性。
提取 $objFromJson
的属性是通过 PowerShell 添加(除其他外)隐藏的 .PSObject
属性 到所有对象,其自己的 .Properties
属性 包含所有对象的 属性 定义 的集合(名称、值、附加元数据,例如 属性 的类型、...);例如:
PS> $objFromJson.Object1.PSObject.Properties
MemberType : NoteProperty
IsSettable : True
IsGettable : True
Value : o11
TypeNameOfValue : System.String
Name : key1
IsInstance : True
# ... remaining properties
输出 $objFromJson
's property definitions and extracting only the definitions' Name
和 Value
属性的集合是朝着正确方向迈出的一步:
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
我正在尝试从 JSON 文件创建一个 table 我从 RESTful API.
收到当我打印 json 对象的 属性 时,我得到如下输出:
PS> 写入输出 JSON.Object 对象 1:@{key1=属性;键2=属性;键3=属性; key4=属性} 对象 2:@{key1=属性;键2=属性;键3=属性; key4=属性} 对象 3:@{key1=属性;键2=属性;键3=属性; key4=属性} 对象 4:@{key1=属性;键2=属性;键3=属性; key4=属性}
我想看到的输出是这样的:
名称key1 key2 key3 key4 ----- ----- ----- ---- ---- 对象 1 属性 属性 属性 属性 Object2 属性 属性 属性 属性 Object3 属性 属性 属性 属性
此外,是否可以避免显示特定键及其属性?
示例:
Name key1 key2 key4 # ← 不显示key3 ----- ----- ----- ---- 对象 1 属性 属性 属性 对象 2 属性 属性 属性 Object3 属性 属性 属性
您需要将父键名作为 属性 Name
添加到嵌套对象中:
$json.Object | ForEach-Object {
foreach ($p in $_.PSObject.Properties) {
$p.Value | Select-Object @{n='Name';e={$p.Name}},*
}
}
请注意,默认情况下 PowerShell 将以列表形式呈现输出,因为您的对象具有 4 个以上的属性。通过 Format-List -AutoSize
进行管道传输以获得表格输出。
用背景信息补充
让我们定义模拟单个嵌套对象的示例输入,该对象通过 ConvertFrom-Json
:
[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]
这样的类型, 而 具有 explicit formatting definitions defined for them (via *.ps1xml
files and loaded implicitly into the session or explicitly via Update-FormatData
),PowerShell 根据 属性数量 类型:
- 具有最多 4 个属性的类型隐式使用
Format-Table
- 具有 5 个或更多属性的类型隐式使用
Format-List
问题中的样本输入大概是删节;真正只有 4 个属性时,会产生 表格 显示。
属性本身 是通过调用 .PSObject.ToString()
对其值进行渲染的,这通常与您希望的表示相同如果您在双引号字符串中引用对象,则获取,除了后者始终使用 culture-invariant 格式,而 .ToString()
将尊重当前文化,如果类型支持它。
在 [pscustomobject]
实例的情况下,这会导致 类似于 哈希表文字的表示,但不是一个(有关背景信息,请参阅 this answer);例如:
PS> $objFromJson.Object1.PSObject.ToString()
@{key1=o11; key2=o12; key3=o13; key4=o14}
根据需要重塑数据:
无法直接使用 Format-Table
等格式化 cmdlet 来产生所需的输出 - 数据必须 重塑 第一:
具体来说,对象 $objFromJson
的属性必须重塑为 自定义对象的集合 :
其
Name
属性 包含给定 属性 的 name 和其其他属性是那个属性的值对象的属性;换句话说:输入 属性 的 value 的属性必须成为输出对象本身的属性。
提取 $objFromJson
的属性是通过 PowerShell 添加(除其他外)隐藏的 .PSObject
属性 到所有对象,其自己的 .Properties
属性 包含所有对象的 属性 定义 的集合(名称、值、附加元数据,例如 属性 的类型、...);例如:
PS> $objFromJson.Object1.PSObject.Properties
MemberType : NoteProperty
IsSettable : True
IsGettable : True
Value : o11
TypeNameOfValue : System.String
Name : key1
IsInstance : True
# ... remaining properties
输出 $objFromJson
's property definitions and extracting only the definitions' Name
和 Value
属性的集合是朝着正确方向迈出的一步:
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