[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Understanding xsl:key

Subject: Re: Understanding xsl:key
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Thu, 17 Aug 2000 13:17:02 +0100
xsl test key
Heiner,

When you define the key:

> <xsl:key name="test" match="title" use="name"/>

Then you are setting up a number of associations between 'title' nodes and
key values given to them through their 'name' child:

node		key value
title[1]	'Design Patterns'
title[2]	'Pattern Hatching'
title[3]	'Building Applications'

When you use:

  key('test', 'Pattern Hatching')

you are saying "What nodes within the 'test' key have the key value of
'Pattern Hatching'?"

The answer is always the second title (in your example), so that node is
always returned as a result.

When you test on that node as in:

  <xsl:if test="key('test', 'Pattern Hatching')">
    ...
  </xsl:if>

then the test expression is evaluated and then converted to a boolean.
When node sets are converted to a boolean value, they return true() if
there is a node in the node set, and false() if not.  In your case, since
the key() does return a node, the test is always true, so the contents of
xsl:if are always used, and you get information about all the books.

>Now, I'd expect the xsl:if to make sure only "name" elements that are 
>children of "title" and have the content "Pattern Hatching"  are 
>shown.

If you are matching all books, as you are here, then it's easy to test
whether a book that you have has a 'title' child with a 'name' child that
has a content of 'Pattern Hatching'.  You don't need key() to do it:

  <xsl:if test="title/name = 'Pattern Hatching'">
    ...
  </xsl:if>

Keys are really useful for *selecting* nodes that you want to process.  So
if you only wanted to process the book with the title 'Pattern Hatching',
then you could use something like:

<xsl:template match="booklist">
  <booklist>
    <xsl:apply-templates
        select="key('test', 'Pattern Hatching')" />
  </booklist>
</xsl:template>

<xsl:template match="title">
  <node>
    <xsl:value-of select="name" />
  </node>
</xsl:template>

If you want to give any information about the book aside from its title,
you also may be better off changing your key so that it matches on *books*
rather than on their *titles*.  The match expression for a key should match
the nodes that you're actually interested in, rather than one of their
children, or an attribute.  It's the 'use' expression that lets you select
*what* is interesting about the node (e.g. the name child of the title child):

<xsl:key name="test" match="book" use="title/name" />

and then:

<xsl:template match="booklist">
  <booklist>
    <xsl:apply-templates select="key('test', 'Pattern Hatching')" />
  </booklist>
</xsl:template>

<xsl:template match="book">
  <node>
    <xsl:value-of select="title/name" />
  </node>
</xsl:template>

I hope that this clears things up somewhat.

Cheers,

Jeni

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



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


Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.