", "family" /> ", "family" /> ", "family"/>

Access Complex Nested Object Keys in a Powershell (Keys Name)

210 Views Asked by At

I try to convert my json data to the specific arraylist

My Sample JSON File

$personData = @'
{
  "persons": [{
      "johndoe": [{
          "id": "4334234 <>",
         
          "family_adress": {
            "mother": "address of family",
            "father": "",
            "brother": "address of family"
          },
          
          "childiren": {
            "first": 1024,
            "second":128
          },

          "years_activity": {
              "2021":  [ "sample entry-1", "sample entry-2" ],
              "2022":  [ "sample entry-1", "sample entry-2" ]
          }
     }],

      "johndoe2": [{
          "id": "4334234 <>",
         
          "family_adress": {
            "mother": "address of family...",
            "father": "",
            "brother": "...address of family"
          },
          
          "childiren": {
            "first": 25,
            "second": 12
          },

          "years_activity": {
              "2021":  [ "sample entry-4", "sample entry-r" ],
              "2022":  [ "sample entry-5", "sample entry-s" ]
          }
     }]

  }]
}
'@

My Function to catch first entry

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
        }
      }
  }
}
$data = $personData | ConvertFrom-Json
$person = Get-FirstPropertyValue $data 'persons'
$propName = @($person.psobject.properties.Name)[0]

write-Host $propName
@($person.psobject.properties.Name)[0].Keys       # Nothing

Q: How can access only nested object name?

My Expected Output:
------------------
family_adress
childiren
years_activity

I want to access, person > johndoe > subkeys -> (if subkeys not has more than one property catch its only name because I want to add them to the arraylist)

1

There are 1 best solutions below

4
yacc On

The JSON looks malformed, persons is not an array but a single struct so indexing with [0] doesn't select johndoe. This makes it an array of structs:

$personData = @'
{
  "persons": [{
    "johndoe": {
      "id": "4334234 <>",
     
      "family_adress": {
        "mother": "address of family",
        "father": "",
        "brother": "address of family"
      },
      
      "childiren": {
        "first": 1024,
        "second":128
      },

      "years_activity": {
          "2021":  [ "sample entry-1", "sample entry-2" ],
          "2022":  [ "sample entry-1", "sample entry-2" ]
      }
    }},{

    "johndoe2": {
      "id": "4334234 <>",
     
      "family_adress": {
        "mother": "address of family...",
        "father": "",
        "brother": "...address of family"
      },
      
      "childiren": {
        "first": 25,
        "second": 12
      },

      "years_activity": {
          "2021":  [ "sample entry-4", "sample entry-r" ],
          "2022":  [ "sample entry-5", "sample entry-s" ]
      }
   }}]
}
'@

And this selects the first user (johndoe) and its property names:

$persons = Get-FirstPropertyValue $data 'persons'
$person = $persons[0]
write-host "person: " ($person | out-string)
$value = $person.psobject.properties.Value
write-host "props: " $value.psobject.properties.name # props:  id family_adress childiren years_activity