Sample Data

Let’s start with some sample data, and store it in a file c:\temp\university-node.xml.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<University>
  <Department>
    <Name>English</Name>
    <Chair>Professor Lit</Chair>
  </Department>
  <Department>
    <Name>Mathematics</Name>
    <Chair>Professor Calc</Chair>
  </Department>
  <Department>
    <Name>Biological Science</Name>
    <Chair>Professor Nature</Chair>
  </Department>
  <Department>
    <Name>Environmental Science</Name>
    <Chair>Professor Green</Chair>
  </Department>
</University>

Let’s format the same data as attributes, and store it in a file c:\temp\university-attribute.xml.

1
2
3
4
5
6
<University>
  <Department Name="English" Chair="Professor Lit" />
  <Department Name="Mathematics" Chair="Professor Calc" />
  <Department Name="Biological Science" Chair="Professor Nature" />
  <Department Name="Environmental Science" Chair="Professor Green" />
</University>

Let’s say we want to list all the department information in a table.

Using Select-Xml to parse XML

I can apply the same code to either xml layout.

1
2
[xml]$xmlNodeDoc = Get-Content -Path 'c:\temp\university-node.xml'
Select-Xml -Xml $xmlNodeDoc -XPath '/University/Department' | Select-Object -ExpandProperty Node
1
2
[xml]$xmlAttributeDoc = Get-Content -Path 'c:\temp\university-attribute.xml'
Select-Xml -Xml $xmlAttributeDoc -XPath '/University/Department' | Select-Object -ExpandProperty Node

Now I just want to find the departments where “Science” is in the Name.

1
2
[xml]$xmlNodeDoc = Get-Content -Path 'c:\temp\university-node.xml'
Select-Xml -Xml $xmlNodeDoc -XPath '/University/Department[contains(Name/text(), "Science")]' | Select-Object -ExpandProperty Node
1
2
[xml]$xmlAttributeDoc = Get-Content -Path 'c:\temp\university-attribute.xml'
Select-Xml -Xml $xmlAttributeDoc -XPath '/University/Department[contains(@Name, "Science")]' | Select-Object -ExpandProperty Node

Using objects to parse XML

By prefixing the xml variable name with [xml], PowerShell converts the xml text into objects that you can work with using dot notation. Attributes and nodes use the same dot notation.

1
2
[xml]$xmlNodeDoc = Get-Content -Path 'c:\temp\university-node.xml'
$xmlNodeDoc.University.Department | Select-Object
1
2
[xml]$xmlAttributeDoc = Get-Content -Path 'c:\temp\university-attribute.xml'
$xmlAttributeDoc.University.Department | Select-Object

Like before, now I just want to find the departments where “Science” is in the Name.

1
2
[xml]$xmlNodeDoc = Get-Content -Path 'c:\temp\university-node.xml'
$xmlNodeDoc.University.Department | Where-Object {$_.Name -like "*Science*"} 
1
2
[xml]$xmlAttributeDoc = Get-Content -Path 'c:\temp\university-attribute.xml'
$xmlAttributeDoc.University.Department | Where-Object {$_.Name -like "*Science*"} 

Convert data to XML

This example takes output from the Get-Service cmdlet and saves it to a file as xml.

1
2
3
4
Get-Service | 
    Select-Object -Property DisplayName,Status | 
    ConvertTo-Xml -As 'String' -NoTypeInformation | 
    Out-File 'c:\temp\get-service.xml'