Search code examples
arraysjsonpowershellnestedconvertfrom-json

Powershell ConvertFrom-Json: Selecting Value of Nested Array Based on Property Name


I have a json file that I'm trying to export to csv using powershell, but I only need certain nested values. It looks like the following:

[
   {
      "ItemName": "A",
      "ItemID": "I001",
      "ItemDate": "2021-03-01",
      "ItemValue": "1000",
      "ItemTags": [
         {
            "Name": "First tag name",
            "Value": "medium"
         },
         {
            "Name": "Another tag name",
            "Value": "red"
         },
         {
            "Name": "Tag 3",
            "Value": null
         },
         {
            "Name": "Tag 4",
            "Value": "Yes"
         }
      ]
   },
   {
      "ItemName": "B",
      "ItemID": "I002",
      "ItemDate": "2021-02-01",
      "ItemValue": "3000",
      "ItemTags": [
         {
            "Name": "First tag name",
            "Value": "best"
         },
         {
            "Name": "Another tag name",
            "Value": "green"
         },
         {
            "Name": "Tag 3",
            "Value": null
         },
         {
            "Name": "Tag 4",
            "Value": "No"
         }
      ]
   }
]

The nested "ItemTags" portion is where I'm having trouble. The actual json file has dozens of Item Tags and ordering of them can vary so what I'd like to do is only select ones based on the "Name" of the ItemTag, for example select the ItemTag Value where ItemTag Name is Tag 4.

I've only been able to do it based on the order like this:


$obj1 = Get-Content -Path "C:\Temp\sample.json"  | ConvertFrom-Json
$obj1 | select ItemName, ItemID, ItemDate, ItemValue, @{Name = 'Tag 4'; Expression ={$_.ItemTags[3].Value}} | Export-CSV "C:\Temp\items.csv" -NoTypeInformation

But again, because the ItemTags ordering can be different from one day to the next, this won't quite do it. How would I modify this to select based on the ItemTag Name of "Tag 4"?


Solution

  • This works for me:

    Expression = { ($_.ItemTags | Where-Object Name -eq 'Tag 4').Value }
    

    By specifying just $_.ItemTags we are creating an array of all ItemTags objects. Using Where-Object we select only these elements, whose Name member equals 'Tag 4'. Finally we get the Value member from the resulting elements. Note this wil be an array, when there are more than one matching elements, which is true for your sample data ('Yes','No').