#PSTip Using XPath in PowerShell, Part 5

XPath has one big disadvantage–it’s case sensitive. Unlike regular expressions, there is no way to “turn it off”. But there is a way around it. To make part of the query case insensitive we have to use translate() function. This function takes three arguments: string that will be modified, string that lists “originals”, and finally string that contains “replacements”. If there is more characters in the second string, then any extra character will be removed. For example, if we want any node element with attribute Name equal to ‘first’ (case-insensitive):

$caseInsensitive = @'
    //node[
        translate(@Name, "FIRST", "first") = 'first'
    ]
'@

Select-Xml -XPath $caseInsensitive -Path .\Test.xml |
    ForEach-Object { $_.Node.Name }

First

Note: You can find the code and input files here.

But that’s not the only situation when translate() function may come in handy. Because character than we translate to can be the same for each character replaced, we can write queries that behave almost like regular expressions. Good example would be a query to get all headings in XHTML document. Regular expression that matches node names for headings is ‘^h[1-6]$’. To get the same in XPath we would need to translate any number between 1 and 6 to the same character (e.g. ‘#’) and test if result is ‘h#’:

$almostRegex = @'
    //*[
        translate(name(), '123456', '######') = 'h#'
    ]
'@

Select-Xml -XPath $almostRegex -Path .\TestPage.xhtml | 
    Select-Object Node

Node
---- 
h1
h1
h2
h3
h6
h1
h1
Share on: