以下代码定义并使用 functionGet-FirstPropertyValue
,该 函数 对具有给定名称的对象图内的第一个属性
执行 深度优先 的 递归搜索 ,并假设其值为非null:
# Function that returns the value of the first property with the given # name found during recursive depth-first traversal of the given object.# Note that null-valued properties are ignored.function Get-FirstPropertyValue($obj, $propName) { $propNames = $obj.psobject.properties.Name if ($propName -in $propNames) { $obj.$propName } else { foreach ($iterPropName in $propNames) { if ($null -ne ($val = Get-FirstPropertyValue $obj.$iterPropName $propName)) { return $val } } }}# Input JSON$json = @'{ "nodes": { "oTUltX4IQMOUUVeiohTt8A": { "name": "H5dfFeA", "transport_address": "127.0.0.1:9300", "host": "127.0.0.1", "ip": "127.0.0.1:9300", "tasks": { "oTUltX4IQMOUUVeiohTt8A:124": { "node": "oTUltX4IQMOUUVeiohTt8A", "id": 124, "type": "direct", "action": "cluster:monitor/tasks/lists[n]", "start_time_in_millis": 1458585884904, "running_time_in_nanos": 47402, "cancellable": false, "parent_task_id": "oTUltX4IQMOUUVeiohTt8A:123" } } } }}'@# Convert the JSON to a [pscustomobject] graph with ConvertFrom-Json.$objFromJson = $json | ConvertFrom-Json# Using the function defined above, get the first 'tasks' object found# during recursive depth-first traversal.$tasks = Get-FirstPropertyValue $objFromJson 'tasks'# Get the name of the resulting object's first property.$propName = @($tasks.psobject.properties.Name)[0]# Extract the .id property from the object stored in the first property.$tasks.$propName.id以上收益:
124
一个 更简洁但更晦涩且可能更慢的替代方法 是 将JSON输入转换为XML,然后使用 XPath对其 进行查询:
# Input JSON$json = @'{ "nodes": { "oTUltX4IQMOUUVeiohTt8A": { "name": "H5dfFeA", "transport_address": "127.0.0.1:9300", "host": "127.0.0.1", "ip": "127.0.0.1:9300", "tasks": { "oTUltX4IQMOUUVeiohTt8A:124": { "node": "oTUltX4IQMOUUVeiohTt8A", "id": 124, "type": "direct", "action": "cluster:monitor/tasks/lists[n]", "start_time_in_millis": 1458585884904, "running_time_in_nanos": 47402, "cancellable": false, "parent_task_id": "oTUltX4IQMOUUVeiohTt8A:123" } } } }}'@$parent = 'tasks'$prop = 'id'$propType = 'int'$json | ConvertFrom-Json | ConvertTo-Xml -Depth ([int]::MaxValue) | Select-Xml "//Property[@Name='$parent']/*/*[@Name='$prop']/text()" | ForEach-Object { $_.Node.InnerText -as $propType }


