Public/Select-XMLNode.ps1

function Select-XMLNode {
  [CmdletBinding()]
  Param (
    [Parameter (
      Position    = 1,
      Mandatory   = $true,
      HelpMessage = "XML content"
    )]
    [ValidateNotNullOrEmpty()]
    [System.XML.XMLDocument]
    $XML,
    [Parameter (
      Position    = 2,
      Mandatory   = $true,
      HelpMessage = "XPath corresponding to the node"
    )]
    [ValidateNotNullOrEmpty()]
    [String]
    $XPath,
    [Parameter (
      Position    = 3,
      Mandatory   = $false,
      HelpMessage = "Namespace"
    )]
    [ValidateNotNullOrEmpty()]
    [String]
    $Namespace = $XML.DocumentElement.NamespaceURI
  )
  Begin {
    # Get global preference variables
    Get-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
  }
  Process {
    # Variables
    $Delimiter          = "/"
    $Alias              = "x"
    # Check PowerShell version to determine if sanitation can be performed
    if ($PSVersionTable.PSVersion.Major -ge 5) {
      $SpecialCharacters  = [RegEx]::New('^[/.@]*')
      if ($XPath -match $SpecialCharacters) {
        $Prefix = $Matches[0]
        $XPath  = $XPath -replace $SpecialCharacters, ''
      }
    } else {
      # Else skip sanitation check
      Write-Log -Type "DEBUG" -Object "XPath sanitation could not be performed due to the PowerShell version $($PSVersionTable.PSVersion.Major) limitations"
      Write-Log -Type "DEBUG" -Object $XPath
    }
    # Get namespace
    $NamespaceManager = New-Object -TypeName "Xml.XmlNamespaceManager" -ArgumentList $XML.NameTable
    $NamespaceManager.AddNamespace($Alias, $Namespace)
    # Split XPath to identify nodes
    $Nodes = $XPath.Split($Delimiter)
    $PrefixedNodes = New-Object -TypeName "System.Collections.ArrayList"
    # Prefix nodes with namespace (alias)
    foreach($Node in $Nodes) {
      if ($Node) {
        [Void]$PrefixedNodes.Add("${Alias}:${Node}")
      }
    }
    # Join prefixed-nodes to create new XPath with namespace
    $XPathWithNamespace = $PrefixedNodes -join $Delimiter
    # Check XPath prefix
    if ($Prefix) {
      $XPathWithNamespace = $Prefix + "" + $XPathWithNamespace
    }
    # Select and return nodes
    $SelectedNodes = $XML.SelectNodes($XPathWithNamespace, $NamespaceManager)
    return $SelectedNodes
  }
}