1

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
Frode F.
  • 52,376
  • 9
  • 98
  • 114
user2176024
  • 41
  • 1
  • 6
  • 2
    What does your XML look like? Please present us with what we need to replicate your issue. [Creating an MCVE](https://stackoverflow.com/help/mcve) – EBGreen Mar 28 '18 at 15:32
  • 1
    If the XML is using namespace, I don t know why would you need to see the XML. Select-Xml -Xml $xdoc -XPath works find on a single node, but all I m asking if you know of a way to combine more then one node to the Xpath please let me know. – user2176024 Mar 28 '18 at 18:32
  • 1
    It does help to specify the correct namespace in `$ns`. Updated question. Not sure what you mean about combine more than one node. Do you have an example of what you want (output)? – Frode F. Mar 28 '18 at 18:34
  • Well, it is really a request for a way for us to replicate the issue that you are seeing. – EBGreen Mar 28 '18 at 18:39
  • Hi EBGreen, well may I m not making my self-clear to the problem, the code I have in the upper part will work fine for a single node. meaning if I just want to see all the values for releases it will show me all the values. If I want to see all the values for the hotfixes it will show me all those values that are associated to those tags. What I m trying to make is a header row with the version then right below it will have the values from hotfixref ex. release value /r /n hfref DE001 blah blah blah – user2176024 Mar 28 '18 at 19:41
  • this is what I trying to accomplish: ns = @{e ='http://nexidia.com/nia/hotfix/manifest'} $items =Select-Xml -Xml $xdoc -XPath '//e:release/e:hotfixref' -Namespace $ns Select-Object -ExpandProperty node As you can see, I have 2 nodes in my xpath that I trying to output as part of my results. when I do this, it does not work. Now if I just left one of the nodes in there, and ran the statement I would get my result set for that node. – user2176024 Mar 28 '18 at 22:03
  • So you want an xpath that matches "either this or that"? But why? release is the parent of the hotfixref-nodes. Why not get release and use PowerShell to access the child nodes? See answer for example – Frode F. Mar 29 '18 at 08:48

1 Answers1

0

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.

RJFalconer
  • 10,890
  • 5
  • 51
  • 66
Frode F.
  • 52,376
  • 9
  • 98
  • 114
  • Thank you, I came up with the same conclusion last night here is a snippet of what I wrote: ` foreach( $n in $ns){ $items =Select-Xml -Xml $xdoc -XPath '//e:release' -Namespace $n $items1 =Select-Xml -Xml $xdoc -XPath '//e:hotfixref' -Namespace $n } $values += $items + $items1 $values | Select-Object -ExpandProperty node | select name, description ` – user2176024 Mar 29 '18 at 09:43
  • I must say I was on the right path, but again working with PowerShell and XML is kind of new to me. Most of the stuff I do write involves search logs and building other tools for troubleshooting issues. – user2176024 Mar 29 '18 at 09:58
  • You'll get there. I didn't understand why you would loop `$ns`. It won't work because it's a hashtable and you only had one namespace in there so there's no need for a loop – Frode F. Mar 29 '18 at 09:59
  • If you ever need a script that will search for "select string" that will build a unc path, will search any remote server no matter what the drive letter is and find the pattern you are looking for in logs. I have that. – user2176024 Mar 29 '18 at 16:26