xml editor

Supported platforms

Compatible with Windows7 & Mac OS X Snow Leopard

Ready for data server software
[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: Understanding xsl:key


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

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
XML Editor | XML Author | WYSIWYG Editors | Schema Editor | XSD Documentation | XSL/XSLT Editor | XQuery | XML Databases | SVN Client
© 2002-2011 SyncRO Soft Ltd. All rights reserved. | Sitemap | Privacy Policy | This website was created & generated with <oXygen/>®XML Editor