Re: [xsl] match selection formulae

Subject: Re: [xsl] match selection formulae
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Fri, 7 Sep 2001 11:15:32 +0100
Hi Roger,

> I had a selection formula so;
> <xsl:template match="lg[@type='stanza' | @rend='italic']">
> </xsl:template>
> <xsl:template match="lg[@type='stanza' | @rend='']">
> </xsl:template>

Really? I think most XSLT processors would raise an error with these -
probably you mistyped in the mail and meant that you had:

  lg[@type = 'stanza' or @rend = 'italic']
  lg[@type = 'stanza' or @rend = '']

> In my naiveity, I thought that @rend='' would be the equivalent of
> testing for the non-existence of an attribute - however, not(@rend)
> doesn't appear to work either. I'm using Xalan 2. what's the correct
> way for testing for the non-existence of an attribute (or an element
> come to that)?

Paths like @rend result in a node set. When you convert a boolean to a
node set then you get true if the node set has any nodes in, and false
if it doesn't. So to test whether @type = 'stanza' or the rend
attribute is not present, then use:

  lg[@type = 'stanza' or not(@rend)]

> More distressingly, the first template always got ignored, not
> matter what pattern I tried with the second. Why did it fail?

Both the first and second template will match elements like:

  <lg type="stanza" />

Because they both accept lg elements whose @type attribute equals
'stanza'. You should try to avoid having two templates that match the
same node, but if it happens then an XSLT processor will recover by
choosing the later template in the stylesheet. If you want to give the
first template priority, then you should add a priority attribute to

<xsl:template match="lg[@type = 'stanza' or @rend = 'italic']"

Alternatively, you could change the match patterns so that they match
different kinds of lg elements. For example, perhaps you meant the
first to match lg elements whose @type = 'stanza' *and* @rend =
'italic', while you want the second to match those lg elements whose
@type = 'stanza' *and* have no @rend attribute, in which case you
should use:

  lg[@type = 'stanza' and @rend = 'italic']
  lg[@type = 'stanza' and not(@rend)]

I hope that helps,


Jeni Tennison

 XSL-List info and archive:

Current Thread