[xml] $xml = "<TOP>
<A>
<X><match>yes</match></X>
<X><match>yes</match></X>
<Y><match>yes</match></Y>
</A>
<B>
<X><match>yes</match></X>
<Z><match>yes</match></Z>
</B>
</TOP>"
$matches = $xml.SelectNodes("//match")
$previous = ""
foreach($match in $matches)
{
$current = $match.ParentNode.ParentNode.Name
if($current -eq $previous)
{
write-host "Same ancestor!:" $match.ParentNode.ParentNode.OuterXml
}
$previous = $match.ParentNode.ParentNode.Name
}
Using xpath and powershell I find all matching nodes, but also want to determine if the nodes have the same ancestors X level op. In the example I have compared 2 level up and only for 2 nodes (current and previous) at the time. I believe there is a better solution using xpath, when looping the matches
I have tried using something like /TOP/A[//X[1]/match][//X[2]/match]
but is stuck
Basically I want to tell that of the 5 matching nodes 3 share the same ancestor whereas the last 2 node share the same ancestor.
CodePudding user response:
You should not compare the names, you should compare the nodes themselves.
$xml = [xml]"<TOP>
<A>
<X><match>yes</match></X>
<X><match>yes</match></X>
<Y><match>yes</match></Y>
</A>
<A>
<X><match>yes</match></X>
<Z><match>yes</match></Z>
</A>
</TOP>"
$matches = $xml.SelectNodes("//match")
foreach ($match in $matches)
{
$current = $match.ParentNode.ParentNode
if ($current -eq $previous)
{
write-host "Same ancestor!:" $current.OuterXml
}
else
{
write-host "Different ancestor!:" $current.OuterXml
}
$previous = $current
}
prints
Different ancestor!: <A><X><match>yes</match></X><X><match>yes</match></X><Y><match>yes</match></Y></A>
Same ancestor!: <A><X><match>yes</match></X><X><match>yes</match></X><Y><match>yes</match></Y></A>
Same ancestor!: <A><X><match>yes</match></X><X><match>yes</match></X><Y><match>yes</match></Y></A>
Different ancestor!: <A><X><match>yes</match></X><Z><match>yes</match></Z></A>
Same ancestor!: <A><X><match>yes</match></X><Z><match>yes</match></Z></A>
CodePudding user response:
If I've understood correctly, Consider
count($a/ancestor::X | $b/ancestor::X) = 1
to test if $a
and $b
have the same X ancestor.
From XPath 2.0 there is an "is" operator to make this simpler
$a/ancestor::X is $b/ancestor::X