[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] Finding another element with the same name as the current node


Subject: Re: [xsl] Finding another element with the same name as the current node
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Thu, 1 Feb 2001 13:51:23 +0000

Hi Jo,

> My xml document has two main "branches" and while processing
> elements in one branch I need to find an element in the other branch
> with the same name and extract the value of one of its attributes.
> Is there a way of finding the name of the element currently being
> processed in a for-each loop and inserting it as a variable within
> the loop?

You're almost there.  This is the bit that you're having difficulty
with:

  <xsl:apply-templates select="//branch1/NAME_OF_CURRENT_ELEMENT">

You can get the name of the current element using:

  name(current())

You can test whether the name of some context element is equal to that
name with:

  name() = name(current())

So if you select all the element children of branch1 and then filter
those with a predicate so that only those with the same name as the
current element are selected, then you'll get what you want:

  <xsl:apply-templates select="//branch1/*[name() = name(current())]">

Rather than using name(current()) you may find it clearer to store the
name of the current node in a variable, and then use that:

  <xsl:variable name="el-name" select="name()" />
  <xsl:apply-templates select="//branch1/*[name() = $el-name]" />

[Aside: I've used name() in the above because it looks as though
that's all you need in your example, but if you have namespaces
floating around the place, then you might want to use local-name(),
perhaps combined with namespace-uri() or a namespace-specific node
test instead.]

If you're doing this a lot, you may find it more more efficient to use
a key to allow you quick access into the branch1 elements by name.
The key would look like:

<xsl:key name="branch1-elements"
         match="branch1/*"
         use="name()" />

You could then quickly get at the relevant branch1 element by name
with:

  <xsl:apply-templates select="key('branch1-elements', name())" />

If you don't use a key, it's probably a bit more efficient to store
the branch1 elements in a variable that you create outside the
xsl:for-each, and then index into that list.  This is because building
up a list each time will probably be more work for the processor:

  <xsl:variable name="branch1-elements" select="//branch1/*" />
  <xsl:for-each select="*">
     ...
     <xsl:apply-templates
       select="$branch1-elements[name() = name(current())]" />
     ...
  </xsl:for-each>
  
I hope that helps,

Jeni

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



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



Current Thread
Keywords
xml