key() Function |
References a relation defined with an <xsl:key> element. Conceptually, the key() function works similarly to the id() function, although keys are more flexible than IDs.
Inputs
The name of the key (defined by an <xsl:key> element) and an object. If the object is a node-set, then the key() function applies itself to the string value of each node in the node-set and returns the node-set of the result of all those key() function invocations. If the object is any other type, it is converted to a string as if by a call to the string() function.
Output
A node-set containing the nodes in the same document as the context node whose values for the requested key match the search argument(s). In other words, if our stylesheet has an <xsl:key> element that defines a key named postalcodes based on the <postalcode> child of all <address> elements in the current document, the function call key(postalcodes, '34829') returns a node-set containing all the <address> elements with a <postalcode> element whose value is 34829.
Defined in
XSLT section 12.2, Keys.
Example
To illustrate the power of the key() function, we'll use this document—a truncated version of the glossary we discussed in Chapter 5:
    <?xml version="1.0" ?>
    <glossary>
      <glentry>
        <term id="applet">applet</term>
        <defn topic="Java" language="en">
          An application program,
          written in the Java programming language, that can be
          retrieved from a web server and executed by a web browser.
          A reference to an applet appears in the markup for a web
          page, in the same way that a reference to a graphics
          file appears; a browser retrieves an applet in the same
          way that it retrieves a graphics file.
          For security reasons, an applet's access rights are limited
          in two ways: the applet cannot access the filesystem of the
          client upon which it is executing, and the applet's
          communication across the network is limited to the server
          from which it was downloaded.
          Contrast with <xref refid="servlet"/>.
        </defn>

        <defn topic="Java" language="it">
          [Pretend this is an Italian definition of applet.]
        </defn>
        <defn topic="Java" language="es">
          [Pretend this is a Spanish definition of applet.]
        </defn>
      </glentry>

      <glentry>
        <term id="DMZlong" xreftext="demilitarized zone">demilitarized
          zone (DMZ)</term>
        <defn topic="security" language="en">
          In network security, a network that is isolated from, and
          serves as a neutral zone between, a trusted network (for example,
          a private intranet) and an untrusted network (for example, the
          Internet). One or more secure gateways usually control access
          to the DMZ from the trusted or the untrusted network.
        </defn>
        <defn topic="security" language="it">
          [Pretend this is an Italian definition of DMZ.]
        </defn>
        <defn topic="security" language="es">
          [Pretend this is a Spanish definition of DMZ.]
        </defn>
        <defn topic="security" language="jp">
          [Pretend this is a Japanese definition of DMZ.]
        </defn>
        <defn topic="security" language="de">
          [Pretend this is a German definition of DMZ.]
        </defn>
      </glentry>

      <glentry>
        <term id="servlet">servlet</term>
        <defn topic="Java" language="en">
          An application program, written in the Java programming language,
          that is executed on a web server. A reference to a servlet
          appears in the markup for a web page, in the same way that a
          reference to a graphics file appears. The web server executes
          the servlet and sends the results of the execution (if there are
          any) to the web browser. Contrast with <xref refid="applet" />.
        </defn>
        <defn topic="Java" language="es">
          [Pretend this is a Spanish definition of servlet.]
        </defn>
        <defn topic="Java" language="it">
          [Pretend this is an Italian definition of servlet.]
        </defn>

        <defn topic="Java" language="de">
          [Pretend this is a German definition of servlet.]
        </defn>
        <defn topic="Java" language="jp">
          [Pretend this is a Japanese definition of servlet.]
        </defn>
      </glentry>
    </glossary>
Here's the stylesheet we'll use to process this document. Notice that we define two <xsl:key> elements to index the XML document in two different ways:
    <?xml version="1.0"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" indent="yes"/>
    <xsl:strip-space elements="*"/>

      <xsl:key name="language-index" match="defn" use="@language"/>
      <xsl:key name="term-ids"       match="term" use="@id"/>

      <xsl:param name="targetLanguage"/>

      <xsl:template match="/">
        <xsl:apply-templates select="glossary"/>
      </xsl:template>

      <xsl:template match="glossary">
        <html>
          <head>
            <title>
              <xsl:text>Glossary Listing: </xsl:text>
            </title>
          </head>
          <body>
            <h1>
              <xsl:text>Glossary Listing: </xsl:text>
            </h1>
            <xsl:for-each select="key('language-index', $targetLanguage)">
              <xsl:apply-templates select="ancestor::glentry"/>
            </xsl:for-each>
          </body>
        </html>
      </xsl:template>

      <xsl:template match="glentry">
        <p>
          <b>
            <a>
              <xsl:attribute name="name">
                <xsl:value-of select="term/@id" />
              </xsl:attribute>
            </a>
            <xsl:value-of select="term"/>
            <xsl:text>: </xsl:text>
          </b>
          <xsl:apply-templates select="defn[@language=$targetLanguage]"/>
        </p>
      </xsl:template>

      <xsl:template match="defn">
        <xsl:apply-templates
         select="*|comment()|processing-instruction()|text()"/>
      </xsl:template>

      <xsl:template match="xref">
        <a>
          <xsl:attribute name="href">
            <xsl:text>#</xsl:text><xsl:value-of select="@refid"/>
          </xsl:attribute>
          <xsl:choose>
            <xsl:when test="key('term-ids', @refid)[1]/@xreftext">
              <xsl:value-of select="key('term-ids', @refid)[1]/@xreftext"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:value-of select="key('term-ids', @refid)[1]"/>
            </xsl:otherwise>
          </xsl:choose>
        </a>
      </xsl:template>

    </xsl:stylesheet>
Transforming the glossary with a targetLanguage of en gives these results:
    <html>
    <head>
    <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Glossary Listing: </title>
    </head>
    <body>
    <h1>Glossary Listing: </h1>
    <p>
    <b><a name="applet"></a>applet: </b>
          An application program,
          written in the Java programming language, that can be
          retrieved from a web server and executed by a web browser.
          A reference to an applet appears in the markup for a web
          page, in the same way that a reference to a graphics
          file appears; a browser retrieves an applet in the same
          way that it retrieves a graphics file.
          For security reasons, an applet's access rights are limited
          in two ways: the applet cannot access the filesystem of the
          client upon which it is executing, and the applet's
          communication across the network is limited to the server
          from which it was downloaded.
          Contrast with <a href="#servlet">servlet</a>.
        </p>
    <p>
    <b><a name="DMZlong"></a>demilitarized
          zone (DMZ): </b>
          In network security, a network that is isolated from, and
          serves as a neutral zone between, a trusted network (for example,
          a private intranet) and an untrusted network (for example, the
          Internet). One or more secure gateways usually control access
          to the DMZ from the trusted or the untrusted network.
        </p>
    <p>
    <b><a name="servlet"></a>servlet: </b>
          An application program, written in the Java programming language,
          that is executed on a web server. A reference to a servlet
          appears in the markup for a web page, in the same way that a
          reference to a graphics file appears. The web server executes
          the servlet and sends the results of the execution (if there are
          any) to the web browser. Contrast with <a href="#applet">applet</a>.
        </p>
    </body>
    </html>
Figure C-5 shows how this document looks when it's rendered in a browser. Using a targetLanguage of jp gives us these results instead:

Generated HTML glossary

    <html>
    <head>
    <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Glossary Listing: </title>
    </head>
    <body>
    <h1>Glossary Listing: </h1>
    <p>
    <b><a name="DMZlong"></a>demilitarized
          zone (DMZ): </b>
          [Pretend this is a Japanese definition of DMZ.]
        </p>
    <p>
    <b><a name="servlet"></a>servlet: </b>
          [Pretend this is a Japanese definition of servlet.]
        </p>
    </body>
    </html>
          </programlisting>

When rendered, the document looks like Figure C-6. Notice that we get entirely different results when we change the targetLanguage.

Generated HTML glossary