I would like to get the following sibling C when I'm matching A or A1 template in the following, for the second A or A1 only:
<root>
<A/> <!-- first A -->
<B/>
<A/> <!-- second A -->
<C/>
<A1/>
<B/>
<A1/>
<B/>
<C/>
</root>
If I'm matching the first A, I have not to retrieve anything as there is another A before my C tag.
If I'm matching the second A, I have to retrieve the C tag.
I tried the following without success:
<xsl:template match="A|A1">
<xsl:if test="following-sibling::C[preceding-sibling::A|A1[1] = .]">
It seems to be true in every case but why?
In XSLT 2.0 you could use a test like
following-sibling::C[
(preceding-sibling::A|preceding-sibling::A1)[last()] is current()]
to find all the Cs whose nearest preceding A
or A1
is the one you first thought of. For XSLT 1.0 you'd have to compare generate-id
values instead of using is
following-sibling::C[
generate-id((preceding-sibling::A|preceding-sibling::A1)[last()])
= generate-id(current())]
This would select
<root>
<A/> <!-- nothing -->
<B/>
<A/> <!-- C1 -->
<C/> <!-- this is C1 -->
<A1/> <!-- nothing -->
<B/>
<A1/> <!-- C2 -->
<B/>
<C/> <!-- this is C2 -->
</root>
Your original test
following-sibling::C[preceding-sibling::A|A1[1] = .]
is equivalent to
following-sibling::C[
( preceding-sibling::A | (child::A1[1]) ) = .]
and would select all following C
siblings for whom either (a) any of their preceding A
siblings or (b) their first A1
child has a string value the same as that of the C
itself. All the C
elements in your document satisfy this predicate as every element has the empty string value.