I'm somewhat new to this so any assistance is greatly appreciated.
I need to return the <Amount>
value where the sibling node <Type>
contains the value "BurialFund".
The script I'm using (below the XML example) only returns the first <Amount>
value from the <Asset>
node so I need a way to specify which node to pull from depending on the <Type>
value.
This is the line I need assistance with: $burial = Select-Xml -XPath '//AssetParent/Assets/Asset/Amount'
Other than getting the value I need, this script does what I want - reads from a folder, retrieves the necessary values, and writes to a .csv file.
Thank you in advance!
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:
# Set the directories where this script should read from and write the results to.
$dir = 'C:\Users\username\Documents\XML\BurialAssetExclusion\'
$manifest = 'C:\Users\username\Documents\XML\BurialAssetExclusion\' (Get-Date -Format yyyyMMdd) '.csv'
# Process the XML files.
Get-ChildItem -Path $dir -Filter *xml | ForEach-Object {
# Retrieve values from specified nodes.
$interviewDate = Select-Xml -XPath '//CurrentDate' -Path $_.FullName -ErrorAction SilentlyContinue
$burial = Select-Xml -XPath '//AssetParent/Assets/Asset/Amount' -Path $_.FullName -ErrorAction SilentlyContinue
$dob = Select-Xml -XPath '//DOB' -Path $_.FullName -ErrorAction SilentlyContinue
$lastName = Select-Xml -XPath '//LastName' -Path $_.FullName -ErrorAction SilentlyContinue
$firstName = Select-Xml -XPath '//FirstName' -Path $_.FullName -ErrorAction SilentlyContinue
# If values were retrieved succesfully.
if ($interviewDate -and $burial -and $dob -and $lastName -and $firstName) {
# Create a custom PSObject and set the values to corresponding properties.
# Out-String Trim used to eliminate System.Object[] error.
New-Object PSObject -Property @{
InterviewDate = ($interviewDate.Node.InnerText | Out-String).Trim()
Burial = ($burial.Node.InnerText | Out-String).Trim()
DOB = ($dob.Node.InnerText | Out-String).Trim()
LastName = ($lastName.Node.InnerText | Out-String).Trim()
FirstName = ($firstName.Node.InnerText | Out-String).Trim()
}
}
# Clear values.
Clear-Variable interviewDate, burial, dob, lastName, firstName
# Set order of columns.
# Export data to the CSV file.
} | Select-Object InterviewDate, Burial, DOB, LastName, FirstName | Export-Csv -Path $manifest -NoTypeInformation -append
CodePudding user response:
You can get the text node of the Amount
element, where the sibling element Type
contains the text "BurialFund"
like this, using XPath:
$burial = $xml | Select-Xml -XPath '//AssetParent/Assets/Asset[Type="BurialFund"]/Amount/text()'
$burial.Node.Value # Outputs 5000
Alternatively, use the convenient object access that PowerShell provides, when you load the XML into an XML document:
$xml = [xml]::new(); $xml.Load( $fullPathToXml )
$xml.AssetParent.Assets.Asset.Where{ $_.Type -eq 'BurialFund' }.Amount