Tricky I don’t know how effective it would be or otherwise, but you could rotate the template by the head and move the logic to the predicate (which is allowed to use axes other than the child, attribute and // ):
<xsl:template match="foo//bar[not(preceding::bar/ancestor::foo)]">
(any bar inside a foo if there is no other bar-inside-foo in front of it). Alternatively, you can try a key trick similar to the way Muenchian grouping works, which might be more efficient
<xsl:key name="fooBar" match="foo//bar" use="1" /> <xsl:template match="foo//bar[generate-id() = generate-id(key('fooBar', 1)[1])]">
source share