What is the correct XPath syntax to match both attributes and elements?
More Info
I created the below function to find elements and attributes which contain a given value:
function Get-XPathToValue {
[CmdletBinding()]
param (
[Parameter(Mandatory)]
[xml]$Xml
,
[Parameter(Mandatory)]
[string]$Value
)
process {
$Xml.SelectNodes("//*[.='{0}']" -f ($Value -replace "'","''")) | %{
$xpath = ''
$elem = $_
while (($elem -ne $null) -and ($elem.NodeType -ne 'Document')) {
$xpath = '/' + $elem.Name + $xpath
$elem = $elem.SelectSingleNode('..')
}
$xpath
}
}
}
This matches elements, but not attributes.
By replacing $Xml.SelectNodes("//*[.='{0}']"
with $Xml.SelectNodes("//@*[.='{0}']"
I can match attributes, but not elements.
Example
[xml]$sampleXml = @"
<root>
<child1>
<child2 attribute1='hello'>
<ignoreMe>what</ignoreMe>
<child3>hello</child3>
<ignoreMe2>world</ignoreMe2>
</child2>
<child2Part2 attribute2="ignored">hello</child2Part2>
</child1>
<notMe>
<norMe>Not here</norMe>
</notMe>
</root>
"@
Get-XPathToValue -Xml $sampleXml -Value 'hello'
Returns:
/root/child1/child2/child3
/root/child1/child2Part2
Should Return:
/root/child1/child2/attribute1
/root/child1/child2/child3
/root/child1/child2Part2
What have you tried?
I tried matching on:
//@*|*[.='{0}']
- returns matching elements, but all attributes.//*|@*[.='{0}']
- returns matching attributes, but all elements.//*[.='{0}']|@*[.='{0}']"
- returns matching elements.//@*[.='{0}']|*[.='{0}']"
- returns matching attributes.//(@*|*)[.='{0}']"
- throws an exception.