用通用解决方案补充Doug Maurer 的有用答案:
下面的代码片段定义并调用函数Get-LeafProperty
,它递归地遍历一个对象图——例如由返回的ConvertFrom-Json
——并输出所有叶属性值,以及它们在层次结构中的名称路径。
# Define a walker function for object graphs:
# Get all leaf properties in a given object's hierarchy,
# namely properties of primitive and quasi-primitive types
# (.NET primitive types, plus those that serialize to JSON as a single value).
# Output:
# A flat collection of [pscustomobject] instances with .NamePath and .Value
# properties; e.g.:
# [pscustomobject] @{ NamePath = 'results.users[0].userId'; Value = 1 }
function Get-LeafProperty {
param([Parameter(ValueFromPipeline)] [object] $InputObject, [string] $NamePath)
process {
if ($null -eq $InputObject -or $InputObject -is [DbNull] -or $InputObject.GetType().IsPrimitive -or $InputObject.GetType() -in [string], [datetime], [datetimeoffset], [decimal], [bigint]) {
# A null-like value or a primitive / quasi-primitive type -> output.
# Note: Returning a 2-element ValueTuple would result in better performance, both time- and space-wise:
# [ValueTuple]::Create($NamePath, $InputObject)
[pscustomobject] @{ NamePath = $NamePath; Value = $InputObject }
}
elseif ($InputObject -is [System.Collections.IEnumerable] -and $InputObject -isnot [System.Collections.IDictionary]) {
# A collection of sorts (other than a string or dictionary (hash table)),
# recurse on its elements.
$i = 0
foreach ($o in $InputObject) { Get-LeafProperty $o ($NamePath + '[' + $i++ + ']') }
}
else {
# A non-quasi-primitive scalar object or a dictionary:
# enumerate its properties / entries.
$props = if ($InputObject -is [System.Collections.IDictionary]) { $InputObject.GetEnumerator() } else { $InputObject.psobject.properties }
$sep = '.' * ($NamePath -ne '')
foreach ($p in $props) {
Get-LeafProperty $p.Value ($NamePath + $sep + $p.Name)
}
}
}
}
使用示例:
# Parse sample JSON with multiple hierarchy levels into a [pscustomobject]
# graph using ConvertFrom-Json.
$objectGraphFromJson = @'
{
"results": {
"users": [
{
"userId": 1,
"emailAddress": "jane.doe@example.com",
"attributes": {
"height": 165,
"weight": 60
}
},
{
"userId": 2,
"emailAddress": "john.doe@example.com",
"attributes": {
"height": 180,
"weight": 72
}
}
]
}
}
'@ | ConvertFrom-Json
# Get all leaf properties.
Get-LeafProperty $objectGraphFromJson
上述产量:
NamePath Value
-------- -----
results.users[0].userId 1
results.users[0].emailAddress jane.doe@example.com
results.users[0].attributes.height 165
results.users[0].attributes.weight 60
results.users[1].userId 2
results.users[1].emailAddress john.doe@example.com
results.users[1].attributes.height 180
results.users[1].attributes.weight 72