PowerShell and XML part 1 – Visualize XPath expression


This is supposed to be the start of a small series of posts on how to deal with XML through PowerShell. While PowerShell already comes with built-in support for XML, there is quite a lot to learn. As part of the learning path, there might be some good opportunities where we can try to make things a little bit easier and extend the capabilities of the built-in commands.
Before diving any deeper into the details of PowerShell in conjunction with XML, I would like to start the series with XPath. This post’s goal is not to provide you with an XPath reference nor will it be an extensive tutorial. According to the principle…

Give a man a fish and you feed him for a day; teach a man to fish and you feed him for a lifetime.

… I will rather guide you through the first steps, point you to some references, and share a PowerShell script that will hopefully help you also on journey to learn XPath. In layman’s terms, XPath can be considered as SQL for XML. Hence, it is essential to learn XPath if you would like to do any serious XML (yes, with PowerShell one can get around this by using dot notation and built-in filter commands, but once you know XPath a lot of the tasks can be done easier and more efficient) related job.
Actually I haven’t used XPath a lot so far myself and also never really bothered to learn it either (the latter might have caused the former in this case 😉 ).
In terms of references I can recommend the following as a starting point:

I will use a slightly modified version of the example inventory.xml XML file that Microsoft uses as part of their XPath reference. The file can be downloaded from here.
The easiest way to use XPath through PowerShell is via the Select-XML cmdlet. The query part of Select-XML is basically a wrapper around SelectNodes (with the downside that it does not support most of the XPath functions (more on that in a future post)). The Select-XML cmdlet supports input via Path[], String[] or XML (array of XML modes) through its ParameterSets:

Get-Command Select-XML -Syntax

The XPath expression argument for Select-XML’s XPath parameter is one of the few places where case matters in PowerShell(i.e. XPath expressions are case-sensitive). The output is an array of matching XML nodes. Using above mentioned inventory.xml let’s look at some examples:

$path = 'c:\inventory.xml'
$xml = Select-Xml -Path $path -XPath / 
#Select the first book element that is the child of the bookstore element.
$xml | Select-XML /bookstore/book[1] | foreach { $_.Node }
#Select all the title elements that have a "lang" attribute with a value of "en"
$xml | Select-XML //title[@lang='en'] | foreach { $_.Node }

Before throwing more random XPath examples at you I would like to share ‘Test-XPath’ ( download is available here). Test-XPath loads XML into a tree-view and provides a combobox to type an XPath expression that is used to query parts of the XML, matching XML nodes are then highlighted within the tree-view. If no XML argument is provided Test-XPath will load the mentioned inventory.XML and populate the combobox with most of the example XPath expressions from the Microsoft XPath reference. Test-XPath will hopefully help you to get a better grasp of XPath by example:

While this just scratches the surface of what can be done with XPath I will leave those details for another post (e.g. Namespaces, XPath functions, more general XML related tasks).


Photo Credit: herdiephoto via Compfight cc

2 thoughts on “PowerShell and XML part 1 – Visualize XPath expression

  1. So i’m wondering, if i scrape a webpage with HTMLAgilityPack, that uses XPATH, how can i convert the scraped page into XML so that i can read it with this tool? So then my XPATH learning would be a lot easier.


    1. Better late than never ;-). While there might be ways to do this, I’d honestly use another tool to test XPATH against webpages. You could for instance use Chrome’s built-in Developer tools (e.g. press CTRL+SHIFT+J while on this very page in Chrome and type $x(‘//*[@id=”comment-1463″]/div[1]/p[1]/text()’)).


I'd love to hear what you think

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s