xmlpowershellinnertext

Powershell not showing node text if node has attributes


I try to process Peppol xml invoices. Sometimes the same node has attributes and sometimes does not. How can I get the text of a node regardless of it having attributes?

$xml=[xml]@"
<Invoice>
    <PaymentMeans>
        <PayeeFinancialAccount>
            <ID schemeID="IBAN">BE29 3100 0335</ID>
            <ID2>BE29 3100 0335</ID2>
        </PayeeFinancialAccount>
    </PaymentMeans>
</Invoice>
"@

$Invoice=$xml.Invoice
$BIC=$Invoice.PaymentMeans.PayeeFinancialAccount.ID.InnerText
$BIC2=$Invoice.PaymentMeans.PayeeFinancialAccount.ID2.InnerText
Write-Output "BIC                       : $BIC" 
Write-Output "BIC                       : $BIC2"

.InnerText, .InnerXml, .OuterXml and .'#text' are not the solutions.

A working solution is however the use of select-xml that uses Xpath.

$BIC3=(select-xml 'PaymentMeans/PayeeFinancialAccount/ID' $Invoice).node."#text"
$BIC4=(select-xml 'PaymentMeans/PayeeFinancialAccount/ID2' $Invoice).node."#text"
Write-Output $BIC3 
Write-Output $BIC4 

It seems I have to rewrite the script but I hope there are other solutions as well.


Solution

  • mclayton,: Powershell’s “xml type accelerator” is what lets you navigate xml nodes by name without using the .net DOM methods (e.g. $Invoice.PaymentMeans). If an element contains only inner text, it gets added as a string property on its parent, otherwise it gets added as a System.Xml.XmlElement. You could do something like if($Invoice…ID -is [string]) { # return ID } else { # return ID.InnerText }

    $xml=[xml]@"
    <Invoice>
        <PaymentMeans>
            <PayeeFinancialAccount>
                <ID schemeID="IBAN">BE29 3100 0335 4064</ID>
                <ID2>BE29 3100 0335 4064</ID2>
            </PayeeFinancialAccount>
        </PaymentMeans>
    </Invoice>
    "@
    $Invoice=$xml.Invoice
    $BIC=$Invoice.PaymentMeans.PayeeFinancialAccount.ID
    $BICID=if($BIC -is [string]) { $BIC } else { $BIC.InnerText } 
    Write-Output "BIC: $BICID"