I'm trying to match the first bar
element that occurs as a descendant of a foo
element in an xsl match pattern and struggling. Initial attempt:
<xsl:template match="//foo//bar[1]">
...
</xsl:template>
fails because there are several bar
elements that match. So:
<xsl:template match="(//foo//bar)[1]">
...
</xsl:template>
but that fails to compile.
Tricky. I don't know how efficient or otherwise this would be, but you could turn the pattern on its head and move the logic into a predicate (which is allowed to use axes other than child, attribute and //
):
<xsl:template match="foo//bar[not(preceding::bar/ancestor::foo)]">
(any bar
inside a foo
provided there isn't another bar-inside-a-foo before it). Alternatively you could try a key trick similar to the way Muenchian grouping works, which may be more efficient
<!-- trick key - all matching nodes will end up with the same key value - all
we care about is finding whether a particular node is the first such node
in the document or not. -->
<xsl:key name="fooBar" match="foo//bar" use="1" />
<xsl:template match="foo//bar[generate-id() = generate-id(key('fooBar', 1)[1])]">
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With