Author Posts

January 31, 2018 at 2:45 am

Hello and thank you for taking time to read my post. Here is what I'm trying to do.

I have an XML file that I would like to parse through, and retrieve back specific information.

To make it easy to understand, here is a screenshot of what the XML file looks like: https://imgur.com/a/jYCGR

I would like to parse through the XML and for each Item node, retrieve back the fields indicated in the screenshot. Each of the values retrieved need to be formatted per item node.

Finally, I would love to be able to specify a criteria to look for, and only retrieve that where found.

I have been trying, without luck. Here is what I have been able to come up with:


Select-Xml -Path "my.xml" -XPath "//*" | Select-Object -ExpandProperty Node

The above code actually lists it perfectly. I am just not sure how to select only what I need. Where-object is not working right for me.

Your help is greatly appreciated. When sharing code, this will need to run Windows 7 – Windows 10 computers.

January 31, 2018 at 2:50 pm

I'll apologize if this doesn't work as I'm barely in the beginner phases of parsing XML... And I'm sure someone could to this much cleaner, but this is what I would try:

[xml]$MyXMLFile = gc 'X:\folder\my.xml'
$XMLItem = $MyXMLFile.PatchScan.Machine.Product.Item
$Patch = $XMLItem | where-object {$_.class -eq 'Patch'}
$Patch.BulletinID
$Patch.PatchName
$Patch.Status

January 31, 2018 at 4:04 pm

You're getting close. You're getting hung up exactly where I get hung up. I changed your code a little to show what works

[xml]$MyXMLFile = gc 'X:\folder\my.xml'
$XMLItem = $MyXMLFile.PatchScan.Machine.Product
$Patch = $XMLItem | where-object {$_.name -eq 'Windows 10 Pro (x64)'}
$Patch.SP

Notice I can get here: $MyXMLFile.PatchScan.Machine.Product. Once I add .Item into the mix, it returns no results. If I pipe it to get member, name is Property string Name {get;set;}. Where as Item is: ParameterizedProperty System.Xml.XmlElement Item(string name) {get;}, System.Xml.XmlElement Item(string localname, string ns) {get;}

So using Item, the $Patch variable has nothing in it. The where-object is clearly not picking up anything.

January 31, 2018 at 4:15 pm

What does the XML look like for Product?

January 31, 2018 at 4:28 pm

It should be in that first screenshot. This screenshot shows better how it starts with many product folders, and then in each product folder is many item folders. https://imgur.com/a/83tYi The XML in the product folder I don't care about. I need the individual information in each item folder.

January 31, 2018 at 4:32 pm

I only ask because you're where-object is looking at the product node.

January 31, 2018 at 4:38 pm

Correct. I was only using that as an example, demonstrating that I can get that far. Once I try going down into Item, it doesn't do anything.

Here is another example

I load the XML into an XML Object. Now I try traverse it down to product and it works perfectly:

$xmlobj.PatchScan.Machine.Product | Select-Object -Property Name, SP

Name SP
—- —
Windows 10 Pro (x64) 1607
Internet Explorer 11 (x64) Gold
Windows Media Player 12.0 Gold
MDAC 6.3 (x64) Gold
.NET Framework 4.7 (x64) Gold
MSXML 3.0 SP11
MSXML 6.0 (x64) SP3
DirectX 9.0c Gold
Adobe Flash 23 Gold
VMware Tools x64 Gold
Microsoft Visual C++ 2008 SP1 Redistributable Gold
Microsoft Visual C++ 2008 SP1 Redistributable (x64) Gold

Now add Item in and intellisense puts up a bracket as if Item was a method $xmlobj.PatchScan.Machine.Product.Item( <— See that? So that is why I think for some reason the Item node is doing something strange and that is my roadblock.

January 31, 2018 at 4:42 pm

Yeah, I don't know... Not sure if you've brought your question over to StackOverflow, but I've been able to find a lot more help over there than I do here. I used to get responses really quick here, but lately I get next to nothing, and it typically takes hours, if not days, to get a response. Over there you'll probably have people trying to help you within minutes...

January 31, 2018 at 5:52 pm

Well, I certainly appreciate your help. I have not tried asking on StackOverflow, but I will get to that. Hopefully someone here will chime in sooner or later. Thanks again.

February 3, 2018 at 2:04 am

Hey Chris, I took your advice and ran this question by the StackOverflow site. Here is the code that they came up with and works:

[xml]$xml = Get-Content 'X:\folder\my.xml'
$xml.SelectNodes('//Product/Item[@Class="Patch"]') |
    Select-Object BulletinID, PatchName, Status

XML is a structured text format. It knows nothing about "folders". What you see in your screenshots is just how the the data is rendered by program you use for displaying it.

Anyway, the best approach to get what you want is using SelectNodes() with an XPath expression. As usual.

February 3, 2018 at 2:40 am

Awesome! Glad you got what you looking for!