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:
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:
[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
When I run the above code, it returns no results. However, for testing purposes only, I remove the Item portion. Now, I can get it working by modifying the code above.
I load the XML into an XML Object. Now I try traverse it down to product and it works perfectly:
PS> $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.
This screenshot shows better how it starts with many product folders, and then in each product folder is many item folders.
The XML in the product folder I don't care about. I need the individual information in each item folder.
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.
[xml]$xml = Get-Content 'X:\folder\my.xml'
$xml.SelectNodes('//Product/Item[@Class="Patch"]') |
Select-Object BulletinID, PatchName, Status