Home > Net >  PowerShell / XML Get <Amount> value according to <Type>
PowerShell / XML Get <Amount> value according to <Type>

Time:08-12

I'm not sure if the Title is correct for the question I need answered but here it goes.

I need to grab the <Amount> value nested under a node where the <Type> node contains a particular value.

Specifically, the amount under type <BurialFund>.

The script I'm using (below the XML example) only returns the first amount from the <Asset> node so I need a way to specify which node to pull from according to the <Type> value.

I believe this is the line I need assistance with: $burial = Select-Xml -XPath '//AssetParent/Assets/Asset/Amount'

EXCERPT FROM MY XML:

<AssetParent>
        <Assets>
            <Asset>
                <Type>CheckingAccounts</Type>
                <Amount>100</Amount>
            </Asset>
            <Asset>
                <Type>SavingsAccounts</Type>
                <Amount>200</Amount>
            </Asset>
            <Asset>
                <Type>BurialFund</Type>
                <Amount>5000</Amount>
            </Asset>
        </Assets>
    </AssetParent>

MY SCRIPT

$dir = 'C:\Users\username\Documents\XML\Burial\'
$manifest = 'C:\Users\username\Documents\XML\Burial\'   (Get-Date -Format yyyyMMdd)   '.csv'

Get-ChildItem -Path $dir -Filter *xml | ForEach-Object {

  # Retrieve values from specified nodes.
  $burial = Select-Xml -XPath '//AssetParent/Assets/Asset/Amount' -Path $_.FullName -ErrorAction SilentlyContinue

  # If values were retrieved successfully.
  if ($burial) {

    # Create a custom PSObject and set the values to corresponding properties.
    # Out-String Trim used to eliminate System.Object[] error.
    New-Object PSObject -Property @{
      Burial = ($burial.Node.InnerText | Out-String).Trim()
    }
  }
  
  # Clear values.
  Clear-Variable burial
  
    # Set order of columns.
    # Export data to the CSV file.
  } | Select-Object Burial | Export-Csv -Path $manifest -NoTypeInformation -append

CodePudding user response:

Focusing exclusively on extracting the target amount from the xml and using SelectSingleNode instead of Select-Xml, try this:

$xml = [xml]'your xml above'

$expression = "//Asset[Type='BurialFund']/Amount";
    
$target = $xml.SelectSingleNode($expression);
echo $target.InnerText

Output:

5000

CodePudding user response:

Or simply use dot-notation like:

[xml]$xml = @'
<AssetParent>
    <Assets>
        <Asset>
            <Type>CheckingAccounts</Type>
            <Amount>100</Amount>
        </Asset>
        <Asset>
            <Type>SavingsAccounts</Type>
            <Amount>200</Amount>
        </Asset>
        <Asset>
            <Type>BurialFund</Type>
            <Amount>5000</Amount>
        </Asset>
    </Assets>
</AssetParent>
'@

($xml.AssetParent.Assets.Asset | Where-Object {$_.Type -eq 'BurialFund'}).Amount

Result: 5000

  • Related