XPath can be used to navigate or search an XML document. PowerShell (and .NET) uses XPath 1.0.
The structure and format of XPath queries are beyond the scope of this chapter. However, a number of web resources are available, including https://msdn.microsoft.com/en-us/library/ms256115(v=vs.110).aspx.
Terms and values used in XPath queries, and XML in general, are case-sensitive.
Given the following XML snippet, Select-Xml might use an XPath expression to select the engines of green cars:
$string = @" <?xml version="1.0"?> <cars> <car type="Saloon"> <colour>Green</colour> <doors>4</doors> <transmission>Automatic</transmission> <engine> <size>2.0</size> <cylinders>4</cylinders> </engine> </car> </cars> "@
The -XPath expression and the result are shown here:
PS> Select-Xml -XPath '//car[colour="Green"]/engine' -Content $string | Select-Object -ExpandProperty Node size cylinders ---- --------- 2.0 4
A similar result can be achieved using the SelectNodes method of an XML document:
([Xml]$string).SelectNodes('//car[colour="Green"]/engine')
Select-Xml has an advantage, in that it can be used to work against files directly using the Path parameter:
SelectNodes and XPathNodeList
If the SelectNodes method is called, and there are no results, an empty XPathNodeList object is returned. The following condition is flawed:
$nodes = $xml.SelectNodes('//car[colour="Blue"]')
if ($nodes) {
Write-Host "A blue car record exists"
}
In this case, using the Count property is a better approach:
if ($nodes.Count -gt 1) {
Write-Host "A blue car record exists"
}
If the search is only concerned with the first matching entry, or the search always returns a unique result, the SelectSingleNode method can be used instead.
If the SelectNodes method is called, and there are no results, an empty XPathNodeList object is returned. The following condition is flawed:
$nodes = $xml.SelectNodes('//car[colour="Blue"]')
if ($nodes) {
Write-Host "A blue car record exists"
}
In this case, using the Count property is a better approach:
if ($nodes.Count -gt 1) {
Write-Host "A blue car record exists"
}
If the search is only concerned with the first matching entry, or the search always returns a unique result, the SelectSingleNode method can be used instead.