This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: Filtering the nodes passed to a template...
- To: xsl-list at mulberrytech dot com
- Subject: Re: Filtering the nodes passed to a template...
- From: Mike Brown <mike at skew dot org>
- Date: Thu, 30 Mar 2000 01:07:50 -0700 (MST)
- Reply-To: xsl-list at mulberrytech dot com
> <report>
> <payments>
> <payment id="..."/>
> <payment id="..."/>
> </payments>
> <paymentTypes>
> <paymentType paymentTypeRef="...">
> <paymentType paymentTypeRef="...">
I assume you meant to have empty element tags there.
> </paymentTypes>
> </report>
>
> In the context of <report> I want to pass all the 'paymentTypes/paymentType'
> nodes to a template, where @paymentTypeRef matches any @id attributes in
> <payments>...phew! In the template I'll be outputting the @paymentTypeRef
> (amongst other things), but!!...I only want to output @paymentTypeRef if the
> sibling node before it hasn't got the same value.
Do you really want to process ALL paymentType elements that match any @id,
or do you just want to process the ones that match any @id and that meet
your other criteria?
I suspect the answer is the latter, in which case this is a classic
grouping scenario covered in the FAQ.
<!-- warning: untested, written-late-at-night,
possibly-retracted-in-the-morning code follows -->
<!-- a template that will handle a paymentType element -->
<xsl:template match="paymentType">
<xsl:value-of select="@paymentTypeRef"/>
</xsl:template>
...
<!-- instruction to the xsl processor to go apply the best matching
templates for each of the nodes identified (this goes in some other
template, of course) -->
<xsl:apply-templates
select="/report/paymentTypes/paymentType[
@paymentTypeRef = /report/payments/@id and
@paymentTypeRef != ../following-sibling::paymentType/@paymentTypeRef]"/>
...The reason this should work is because equality comparisons of
node-sets like this return true if each set has a node with the same
string-value.
Now if you really do want to process all paymentType elements and you
were just giving the second condition as a restriction on what gets
output for some of them, just move the second half of the predicate into
the first template:
<xsl:template match="paymentType">
<!-- stuff for just some paymentType elements ... -->
<xsl:if test="@paymentTypeRef != ../following-sibling::paymentType/@paymentTypeRef]">
<xsl:value-of select="@paymentTypeRef"/>
</xsl:if>
<!-- ... other stuff for all paymentType elements ... -->
</xsl:template>
...
<xsl:apply-templates select="/report/paymentTypes/paymentType[
@paymentTypeRef = /report/payments/@id]"/>
Alternatively you could put the predicate into the match attribute and
have separate templates for different classes of paymentType elements.
- Mike
___________________________________________________________
Mike J. Brown, software engineer, Webb Interactive Services
XML/XSL stuff: http://www.skew.org/ http://www.webb.net/
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list