Re: [xsl] How do I check if an element exists with the same name

Subject: Re: [xsl] How do I check if an element exists with the same name
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Mon, 26 Mar 2001 10:09:36 +0100
Hi Tim,

> I'd like to convert this XML to HTML using an XLST. And here comes
> the tricky part, I'd like to let the 'input-field' template check if
> there's a 'missing-field' with the same name. Is this possible and
> if so, how?

First, you should set a variable to hold the name of the field that
you're after.  You don't have to, but it makes things a little easier.
In a template that matches an input-field element, you want the 'name'
attribute to be the value:

  <xsl:variable name="field-name" select="@name" />

Now, you can find a missing-field element with that name by comparing
its 'name' attribute with the value of the variable - if they're the
same then you have the relevant missing-field element:

  //missing-field[@name = $field-name]

If you're doing this a lot (and it looks as though you are), then you
might be better off defining a key so that you can quickly and easily
find the missing-field elements that have a particular name (if such
exist).  The key is defined with an xsl:key element, with the 'match'
attribute matching the elements that you're after (the missing-field
elements) and the 'use' attribute pointing from them to the thing that
you're indexing with (i.e. their 'name' attributes):

<xsl:key name="missing-fields-by-name"
         match="missing-field"
         use="@name" />

When you have this set up, you can get hold of the missing-field
elements called 'loginName', for example, with the expression:

  key('missing-fields-by-name', 'loginName')

So you can replace the path above with:

  key('missing-fields-by-name', $field-name)

Just to explain a little why your code isn't working, here:
  
>         <xsl:apply-templates select="//missing-field[@name={name}]">
>           <xsl:param name="nm">
>             <xsl:value-of select="@name"/>
>           </xsl:param>
>         </xsl:apply-templates>

You're mixing up syntax between expressions and attribute value
templates.  The {...} syntax is attribute value template syntax - it
goes in attribute values that are usually interpreted literally, and
is never used within an XPath expression.

As an aside, you can simplify the way that you set the parameter as
well - you can use the select attribute on xsl:with-param (which is
what you should be using to pass parameters into a template, not
xsl:param which defines a parameter within a template) rather than its
content:

  <xsl:with-param name="nm" select="@name" />

I think that the template that you're after is:
  
<xsl:template match="input-field">
  <xsl:variable name="field-name" select="@name" />
  <tr>
    <td width="150">
      <xsl:value-of select="@caption" />
      <xsl:if test="//missing-field[@name = $field-name]">
        <img src="./mark.gif" />
      </xsl:if>
    </td>
    <td>
      <input type="text" size="20" name="{@name}" />
    </td>
  </tr>
</xsl:template>

Note that XSLT is XML - you have to have quotes around attribute
values (they were missing around td/@width) and all the elements have
to be closed (the img element wasn't).

Also see the simplified syntax for setting the values of attributes
dynamically that I used for the input/@name - that's an example of an
attribute value template.

> Ps. Poster information:
>       Vendor: Microsoft
>       Processor version: Original IE5 (or old version of other processor)

Oh.  Should have read that before answering.  You should upgrade to
MSXML3, really.  Most of the above only works with XSLT, which
original IE5 doesn't support.  Have a look at the MSXML FAQ at
http://www.netcrucible.com/xslt/msxml-faq.htm.

I hope that helps, anyway,

Jeni

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



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


Current Thread