What im trying to do is getting one specific value from nested JSON. Using array keys as expression.
Array with keys and values:
$AccountService = @{
'root.branch.setting1'= 'Val1'
'root.branch.setting2'= 'Val2'
'root.branch.setting3'= 'Val3'
}
Create JSON Object
$json = Get-Content 'C:\Users\ramosfer\Documents\test.json' | ConvertFrom-Json
Get every key from array using a loop to get the value from the JSON. Expecting something like this in the Expression ($json.root.branch.setting1)
$AccountService.GetEnumerator() | % {
$json | Select-Object @{Name="Val"; Expression={$json.$_}}
}
Use this $json.$_ and expect something like this
Val
---
Val1
Val2
Val3
CodePudding user response:
The best way of resolving nested properties is to resolve them one at a time :)
A simpler example, for retrieving just one value:
$json = '{"root":{"branch":{"setting1":"Value 1","setting2":"Value 2","setting3":"Value 3"}}}' |ConvertFrom-Json
# define the "path" to the value we want
$path = 'root.branch.setting1'
# split path into individual property names
$path = $path.Split('.')
# start from the root object and then start "walking" down the object hierarchy
$cursor = $json
foreach($property in $path)
{
# advance cursor one level deeper
$cursor = $cursor.$property
}
# this will now contain "Value 1"
$cursor
You can turn this into a neat little function:
function Resolve-MemberChain
{
param(
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[psobject[]]$InputObject,
[Parameter(Mandatory = $true, Position = 0)]
[string[]]$MemberPath,
[Parameter(Mandatory = $false)]
[string]$Delimiter
)
begin {
if($PSBoundParameters.ContainsKey('Delimiter')){
$MemberPath = $MemberPath.Split([string[]]@($Delimiter))
}
}
process {
foreach($obj in $InputObject){
$cursor = $obj
foreach($member in $MemberPath){
$cursor = $cursor.$member
}
$cursor
}
}
}
Then use it like this:
$json |Resolve-MemberChain 'root.branch.setting1' -Delimiter '.'
Or, as in your case, within a calculated property expression, like so:
$AccountService.GetEnumerator()|%{
$path = $_.Key
$json |Select @{Name='Val';Expression={$_ |Resolve-MemberChain $path -Delimiter .}}
}