powershellxml-namespacesselect-xml

In Powershell how do I get Select-Xml to search multiple Nodes


So I got to say that I m new to using PowerShell for parsing out XML. With that said, how to do I combine multiple -XPath So that I can finishing building out my expression report. Please let me know, I have tried several combinations and none of them seem to work with namespace XML.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" niaVersion="12.0.0.756" xmlns="http://something.com/something/hotfix/manifest">
    <releases>
        <release name="mid November 2017">
            <hotfixes>
                <hotfixref name="DE002" description="" defectSuite="n/a" supportEscalation="n/a" internalNotes="" customer="n/a">
                    <packages>
                        <package type="All" />
                    </packages>
                    <components>
                        <component type="" />
                        <component type="" />
                    </components>
                </hotfixref>
                <hotfixref name="DE5728" description="" defectSuite="DS001" supportEscalation="n/a" internalNotes="" customer="n/a">
                    <packages>
                        <package type="Full" />
                    </packages>
                    <components>
                        <component type="" />
                    </components>
                </hotfixref>
            </hotfixes>
        </release>
    </releases>
</manifest>




[xml]$xdoc=Get-Content $PSScriptRoot\Manifest.xml
$ns = @{test ="http://something.com/something/hotfix/manifest"}
$ver = Select-Xml -Xml $xdoc -XPath '//test:release' -Namespace $ns 
$hfu = Select-Xml -Xml $xdoc -XPath '//test:hotfixref' -Namespace $ns 
foreach ($v in $ver){
$v | Select-Object -ExpandProperty node 
 $hfu |  Select-Object -ExpandProperty node

Solution

  • I can't understand why you need to find both hotfixes and release-nodes. Release is a parent of hotfixes, so simply find all release-nodes and access its child nodes in a loop to find the relevant hotfixes. Ex:

    $xdoc = [xml]@"
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" niaVersion="12.0.0.756" xmlns="http://something.com/something/hotfix/manifest">
        <releases>
            <release name="mid November 2017">
                <hotfixes>
                    <hotfixref name="DE002" description="" defectSuite="n/a" supportEscalation="n/a" internalNotes="" customer="n/a">
                        <packages>
                            <package type="All" />
                        </packages>
                        <components>
                            <component type="" />
                            <component type="" />
                        </components>
                    </hotfixref>
                    <hotfixref name="DE5728" description="" defectSuite="DS001" supportEscalation="n/a" internalNotes="" customer="n/a">
                        <packages>
                            <package type="Full" />
                        </packages>
                        <components>
                            <component type="" />
                        </components>
                    </hotfixref>
                </hotfixes>
            </release>
        </releases>
    </manifest>
    "@
    
    
    
    $ns = @{test ="http://something.com/something/hotfix/manifest"}
    $releases = Select-Xml -Xml $xdoc -XPath '//test:release' -Namespace $ns  
    foreach ($r in $releases){
        "$($r.node.name) contains the following hotfixes:"
        $r.node.hotfixes.hotfixref | Select-Object Name, description, defectSuite
    }
    

    Output:

    mid November 2017 contains the following hotfixes:
    
    name   description defectSuite
    ----   ----------- -----------
    DE002              n/a
    DE5728             DS001
    

    If you really want one xpath-query to find both types, then use | (OR) to separate the xpath-queries. Ex:

    Select-Xml -Xml $xdoc -XPath '//test:release|//test:hotfixref' -Namespace $ns
    
    Node      Path        Pattern
    ----      ----        -------
    release   InputStream //test:release|//test:hotfixref
    hotfixref InputStream //test:release|//test:hotfixref
    hotfixref InputStream //test:release|//test:hotfixref
    

    The problem with this is that you will need logic to detect what type of node you're accessing since it may be release or it may be hotfixref. You will also need extra logic to understand which hotfixref belongs to which release.