views:

240

answers:

4

The default behavior of the xsl on the right-hand side of

http://www.w3schools.com/xsl/tryxslt.asp?xmlfile=cdcatalog&xsltfile=cdcatalog

is to display a 2-column table with the title and artist of each CD in the XML on the left-hand side. (This is shown by the default output under "Your Result" at the bottom.)

I want to modify the xsl to learn about applying xsl functions to text returned from XML elements. (Here is a whole list of xsl string functions.) For example, there is a function fn:upper-case(string) that will convert a string to uppercase.

What, then, would be the minimal modification to the xsl shown there that would produce the same table except with the CD titles all in uppercase?

+2  A: 

Update: Only works in XPath 2.0-supporting processor.

I think the following should do what you want... don't forget to declare the fn namespace (xmlns:fn=...) or declare no namespace at all.

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by XMLSpy® -->
<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:fn="http://www.w3.org/2005/xpath-functions"&gt;

<xsl:template match="/">
  <html>
  <body>
  <h2>My CD Collection</h2>
    <table border="1">
      <tr bgcolor="#9acd32">
        <th>Title</th>
        <th>Artist</th>
      </tr>
      <xsl:for-each select="catalog/cd">
      <tr>
        <td><xsl:value-of select="fn:upper-case(title)"/></td>
        <td><xsl:value-of select="artist"/></td>
      </tr>
      </xsl:for-each>
    </table>
  </body>
  </html>
</xsl:template>
</xsl:stylesheet>
Brabster
There's no `upper-case` in XPath 1.0 (and consequently in XSLT 1.0).
Pavel Minaev
Let me just check that, this stylesheet works fine under Saxon-B 9.1.0.6
Brabster
Yep, Pavel is of course correct. These functions are available in XPath 2.0, so I suspect not on the w3schools site. If you use an XPath 2.0-compliant processor you can use them as above. Otherwise, you'll need to build a function to do it yourself.
Brabster
well traditionally translate has been leaned on for this, as I mentioned, but it's kind of ghetto
annakata
didn't know that @annakata. Think the info warrants an up-vote form me :)
Brabster
A: 

The link to the list of functions that you give is for XPath 2.0, XSLT 2.0 and XQuery 1.0. The stylesheet that you link to is XSLT 1.0, which does not support most of those functions. In particular, it does not support upper-case().

Pavel Minaev
+4  A: 

upper-case is an XSLT 2.0 function. If you happen to have a 2.0 stylesheet (which the example is not) and engine to transform it then using it is as simple as:

<xsl:value-of select="upper-case(title)"/>

However, in the sadly still more common 1.0 your best plan is to use one of:

  • a custom extension (platform varying)
  • the tedious xslt translate function as translate(title,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ') which is crude and problematic with I18N
  • CSS's simple text-transform:uppercase; (generally the best solution because this is usually a style issue not a data issue)
annakata
What is the minimal change to the original page XSL code to apply this "CSS's simple text-transform:uppercase;" solution?
talkaboutquality
@downvoter - wth?
annakata
+2  A: 

Since the XSL on that page is version="1.0", you can change this line

<td><xsl:value-of select="title"/></td>
                          ^^^^^

to this:

<td><xsl:value-of select="translate(title, 'abcdefghijklnmopqrstuvwxyz', 'ABCDEFGHIJKLNMOPQRSTUVWXYZ')"/></td>
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Although with a processor that supports XPath 2.0 you should be able to use this instead:

<td><xsl:value-of select="upper-case(title)"/></td>
                          ^^^^^^^^^^^^^^^^^
system PAUSE
Much appreciate the discussion of versions 1.0 and 2.0 of XPath and XSLT (so that I learn that these versions exist). But I've accepted this simplest answer because (a) it appears to be the correct answer to exactly the question I asked and (b) it works on the page that I gave. But thanks to all responders!
talkaboutquality
Further, this answer makes it very clear to me how I insert a function call into a select statement on an element name. That is, starting with the fragment select="title"it had not been clear to me where I would put the function name and its parentheses. Now it is clear.
talkaboutquality
I guess I can't edit earlier comments? So updating my first comment, I see that this answer also addressed version 2.0 briefly. This answer was short, concise, and correct. That's why I have accepted it.
talkaboutquality