Reputation: 25
I want to get all elements between the first sale and the next sale. Initial XML
<Parent>
<Sale SeqNo="1"/>
<Discount SeqNo="2"/>
<Coupon SeqNo="4"/>
<CouponDetail SeqNo="5"/>
<Sale SeqNo="6"/>
<Sale SeqNo="7"/>
<Sale SeqNo="8"/>
<Payment SeqNo="9"/>
</Parent>
Desired XML:
<Discount SeqNo="2"/>
<Coupon SeqNo="4"/>
<CouponDetail SeqNo="5"/>
I currently have the following applying to a template
following-sibling::*[(number(@SeqNo) < number(following::Sale[1]/@SeqNo))]
Output I am currently getting:
<Discount SeqNo="2"/>
<Coupon SeqNo="4"/>
<CouponDetail SeqNo="5"/>
<Sale SeqNo="6"/>
<Sale SeqNo="7"/>
<Sale SeqNo="8"/>
<Payment SeqNo="9"/>
If I hardcode in the sequence number of the next sale item I get the correct output
following-sibling::*[(number(@SeqNo) < number(6))]
Output:
<Discount SeqNo="2"/>
<Coupon SeqNo="4"/>
<CouponDetail SeqNo="5"/>
What am i missing? Any help appreciated.
Upvotes: 1
Views: 67
Reputation: 113
The issue is the context in which your predicate is being evaluated - it's the particular element child of Parent
that is being tested for whether it should be included in the resulting node-set. So in that context, following::Sale[1]
gives you the first Sale
element following the element being tested, which will always have a higher @SeqNo
, even if it is itself a Sale
element.
What you need to do is store the sequence number of interest in an xsl:variable
prior to doing your select, for instance:
<xsl:variable name="end_seq_no" select="following-sibling::Sale[1]/@SeqNo"/>
<xsl:apply-templates select="following-sibling::*[@SeqNo < $end_seq_no]"/>
Upvotes: 3