Search code examples
xmlpowershell

How to iterate XML values with Powershell and filter by key name?


I have som XML that looks like this

<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<FlowInstance xmlns="http://www.oeplatform.org/version/2.0/schemas/flowinstance"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.oeplatform.org/version/2.0/schemas/flowinstance schema-1161.xsd">
    <Values>
        <donotoutput>
            <Name><![CDATA[donotoutput]]></Name>
            <Value><![CDATA[donotoutput value]]></Value>
        </donotoutput>
        <specifics_test1>
            <Name><![CDATA[Test1]]></Name>
            <Value>Val1</Value>
            <Value>Val2</Value>
            <Value>Val3</Value>
        </specifics_test1>
        <specifics_test2>
            <Name><![CDATA[Test2]]></Name>
            <Value><![CDATA[Test2 value]]></Value>
        </specifics_test2>
        <specifics_test3>
            <Name><![CDATA[Test3]]></Name>
            <Value><![CDATA[Test3 value]]></Value>
        </specifics_test3>
    </Values>
</FlowInstance>

and i want to iterate over the <Values> part of it but only the ones that the key start with "specifics_", how can i do that?

Ive tried this Powershell code

[xml]$xml = Get-Content -Path "C:\Temp\xml\xml_cleaned.xml"

$xml.FlowInstance.Values
$xml.FlowInstance.Values.specifics_test1

gives me the keys and values, but i cant do a loop like this

foreach ($val in $xml.FlowInstance.Values){
    $val
}

and i would also like to get the keys to only parse the ones with "specifics_*" but i cant to that like an hashtable in Powershell with .Keys, how would i do that with this XML?


Solution

  • Since you are dealing with xml, one way to do it is use an xml parser:

    #first, declare namespaces
    $ns = New-Object System.Xml.XmlNamespaceManager($xml.NameTable)
    $ns.AddNamespace("xx", "http://www.oeplatform.org/version/2.0/schemas/flowinstance")
    #note "xx" here is just a nickname for the default namespace
    
    #and now just iterate over them:
    $values = $xml.SelectNodes('//xx:*[starts-with(name(),"specifics_")]/xx:Value',$ns);
    foreach ($value in $values){
       echo $value
     }