Re: [xsl] node vrs node//node?

Subject: Re: [xsl] node vrs node//node?
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Thu, 11 Jul 2002 16:34:11 +0100
Hi Michael,

> Given this xsl:
>
> <xsl:template match="form//checkbox[not(@checked) or @checked != 'yes']">
>  <xsl:apply-templates/>
>  <input type="checkbox" name="{@name}" value="{@value}"/>
> </xsl:template>
>
> <xsl:template match="form//checkbox">
>  <xsl:apply-templates/>
>  <input type="checkbox" name="{@name}" value="{@value}" checked="yes"/>
> </xsl:template>

These templates both have highly specific patterns -- they specify
more than simply the name of the element that they should match -- and
therefore they have the same priority, of 0.5.

When you tell the processor to apply templates to the element:

> <checkbox name="i2b" value="2">Two</checkbox>

it matches both of the templates: it's a checkbox element with a form
ancestor (and thus matches the second template), and it also doesn't
have a checked attribute (and thus matches the first template).

When a processor finds two templates that it could use with a
particular node, and they both have the same priority, it chooses the
last one in the stylesheet, so you end up with the second template
being used, and thus with a checked attribute equal to 'yes'.

To make it work in the way you want it to, you can do any of the
following:

  - swap the templates round
  - assign a higher priority to the first template, using the priority
    attribute
  - change the match attributes so that the second template doesn't
    match the checkbox element as above

I'd probably do a combination of the second and third of these (since
the third possibility also makes the condition less onerous to test),
and have:

<xsl:template match="form//checkbox">
  <xsl:apply-templates/>
  <input type="checkbox" name="{@name}" value="{@value}"/>
</xsl:template>

<xsl:template match="form//checkbox[@checked = 'yes']"
              priority="1">
  <xsl:apply-templates/>
  <input type="checkbox" name="{@name}" value="{@value}"
         checked="checked"/>
</xsl:template>

Note that I've changed the value of the 'checked' attribute in the
result to 'checked'. This is the correct value to use (the name of the
attribute) if you want to create boolean attributes in HTML.

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread