Search notes:

XPath

XPath is a W3C recommendation for navigating XML documents.
XPath is a (read-only) subset of the XQuery language. So, an XPath expression is also an XQuery expression.

Some XPath expressions

/ represents the root of the XML element tree.
/xyz navigates to the node named xyz immediately below the root of the XML element tree.
/abc/*/xyz navigates to node xyz which is below any single node that is below abc immediately under the root element.
//N navigates to any node N below the «actual context»
//N//M navigates to any node N below any node M below the «actual context»
.. get «actual node's» parent node
@foo evaluate to the value of the attribute named @foo (For example //someNode/@theAttribute)
[…] apply a filter, on child node value: //parentNode[childNode = 'xyz'] or on node's attribute: //node[@attr = 'bla']). Some operators include =, !=, or, and, not()

/node/subnode

/node/subnode… traverses the XML document from the root to select one or more nodes:
[xml] $doc = @"
<root>
   <abc>one  </abc>
   <def>two  </def>
   <abc>three <xyz>nine</xyz> </abc>
</root>
"@

foreach ($node in (select-xml -xml $doc -xPath '/root/abc').node) {
  "$($node.InnerText) ($($node.InnerXml))"
}
#
#  one   (one  )
#  three nine (three <xyz>nine</xyz>)
Github repository about-XPath, path: /expressions/slash-node.ps1

@attr

@attr is applied on one (or more?) nodes to return the value of the attribute named attr:
[xml] $doc = @"
<root>
   <foo id='1'>one</foo>
   <bar id='2'>two</bar>
   <baz id='3'>baz</baz>
</root>
"@

$found = select-xml -xml $doc -xPath '/root/bar/@id'
write-host "The id is $($found.node.Value)"
Github repository about-XPath, path: /expressions/at.ps1

Filters

Find an alement with a given attribute-value:
[xml] $doc = @"
<root>
   <elem id='99'>ninety-nine</elem>
   <elem id='42'>forty-two</elem>
   <elem id='17'>seventeen</elem>
</root>
"@

$found = select-xml -xml $doc -xPath '/root/elem[@id="42"]'

$found.Node.InnerText
Github repository about-XPath, path: /expressions/filter/attr.ps1

[]

Find an element (here: <item>) with a child element named <name> whose content is bar, then print the content of another child element of the found element (<value>):
[xml] $doc = @"
<root>
   <item id='1'>
      <name>foo</name>
      <value>42</value>
   </item>

   <item id='2'>
      <name>bar</name>
      <value>99</value>
   </item>

   <item id='3'>
      <name>baz</name>
      <value>7</value>
   </item>

</root>
"@

$item_bar = select-xml -xml $doc -xPath "//item[name='bar']"

write-host "The value of the item whose name is bar is $($item_bar.node.value)"
Github repository about-XPath, path: /expressions/brackets.ps1

See also

The Perl module XML::XPath.
The Excel function filterXml()
The PowerShell cmdLet select-XML allows to formulate XPath queries in PowerShell.
The .NET class System.Xml.XmlNode has two Microsoft extensions to the Document Object Model that return nodes that match an XPath expression: SelectNodes and selectSingleNode.
VBA: MSXML and DOM: selectSingleValue

Index