The key function and the IDREFS datatype

page 95 With the key function, we can search on anything, including the contents of an element. See Section 5.3 for an example of this. For this reason, our call to the key function asking for all the term elements with an id attribute equal to wildcard-char DMZlong pattern- matching returns nothing. Any attribute with a datatype of ID cant contain spaces, so we get no results. There are several ways to deal with this problem; well go through our choices next.

5.2.3.2 Solution 1: Replace the IDREFS datatype

If you consider this a problem and refuse to use the id function, there are several approaches you can take. The most drastic but probably the simplest to implement is to not use the IDREFS datatype at all. You could change the seealso element so that it contains a list of references to other elements: seealso item refid=wildcard-character item refid=DMZlong item refid=pattern-matching seealso This approach has the advantage that we can use the value of all the refid attributes of all item elements with the key function. That means we can search on anything, not just values of attributes. The disadvantage, of course, is that we had to change the structure of our XML document to make this approach work. If you have control of the structure of your XML document, thats possible; its entirely likely, of course, that you cant change the XML document at all. A variation on this approach would be to use a stylesheet to transform the IDREFS datatype into the previous structure.

5.2.3.3 Solution 2: Use the XPath contains function

A second approach is to leave the structure of the XML document unchanged, then use the XPath contains function to find all term elements whose id attributes are contained in the value of the refids attribute of the seealso element. Heres how that would work: xsl:template match=seealso b xsl:textSee also: xsl:text b xsl:variable name=id_list select=refids xsl:for-each select=term xsl:if test=containsid_list, id a href={id} xsl:choose xsl:when test=xreftext xsl:value-of select=xreftext xsl:when xsl:otherwise xsl:value-of select=. xsl:otherwise xsl:choose a xsl:if test=notposition=last xsl:text, xsl:text xsl:if xsl:if xsl:for-each xsl:text. xsl:text xsl:template page 96 Weve done a couple of things here: First, weve saved the value of the refids attribute of the seealso element in the variable id_list . Thats because we cant access it within the for- each element. We can find a given seealso element from within a given term element, but its too difficult to find that element generically from every term element. The simplest way to find the element is to save the value in a variable. Second, we look at all of the term elements in the document. For each one, if our variable containing the refids attribute of the seealso element contains the value of the current term elements id attribute, then we process that term element. Here are the results our stylesheet generates: html head titleGlossary Listing: applet - wildcard charactertitle head body h1Glossary Listing: applet - wildcard characterh1 p ba name=appletaapplet: 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 applets access rights are limited in two ways: the applet cannot access the file system of the client upon which it is executing, and the applets communication across the network is limited to the server from which it was downloaded. Contrast with a href=servletservleta. bSee also: ba href=DMZlongdemilitarized zonea, a href=DMZ DMZa, a href=pattern-matchingpattern-matching charactera, a href=wildcard-charwildcard charactera. p ... There are a couple of problems here. The most mundane is that in our stylesheet, we dont know how many term elements have id attributes contained in our variable. That means its difficult to insert commas correctly between the matching term s. In the output here, we were lucky that the last match was in fact the last term, so the results here are correct. For any seealso element whose refid attribute doesnt contain the id attribute of the last term element in the document, this stylesheet wont work. The more serious problem is that one of the matches is, in fact, wrong. If you look closely at the output, we get a match for the term DMZ , even though there isnt an exact match for its id in our variable. Thats because the XPath contains function says correctly that the value DMZlong contains the id s DMZlong and DMZ . So our second attempt at solving this problem doesnt require us to change the structure of the XML document, but in this case, we have to change some of our ID s so that the problem we just mentioned doesnt occur. Thats probably going to be a maintenance nightmare and a serious drawback to this approach.