Generic XSLT

Whenever I’m creating an XSL style sheet, unless I’m very, very careful, my style sheets are basically a one-trick pony. Yeah, they do that one trick well, but as I said before, I’m paid by the page, not by the line. Maybe this is the reason the style sheets that I create are—hmm, how to put it nicely?—weird. Yes, that’s the word, weird. It isn’t that they don’t work—they work perfectly well. It is more along the lines that I use a lot of relative positioning. Although this approach might seem somewhat dangerous, there are several ways to decrease the danger to tolerable levels. More simply put, take cautions to prevent the style sheets from blowing up and taking the web page out with them. One of these methods is to always make sure that the XML document has the same basic structure, /root/row/node. This makes it far less likely that you will encounter any surprises. Remember back to Chapter 9, “XPath,” to the brief introduction to XPath with all the slashes and asterisks? Well, the asterisks are wildcards, used when the node name is unknown. This means that /*/*/* is the equivalent to /root/row/node—at least, when we want all the nodes that are the second descendant of the root node.

 

Forms

As long as the structure of the XML document is known, it isn’t very difficult to create generic XSL style sheets. Knowing the names of the individual nodes isn’t important, either, although, for the extremely lazy, like myself, the names can be important when creating either labels or column headers. To show what I mean, it is necessary to introduce two XSLT functions. The first of these functions is the name function. It provides the name of the node passed, which, in these cases, is the context node “.”. It returns the actual node name, so if the node name is item_price, then item_price is returned. Yes, I am aware that a label or header with item_price isn’t much better than no label at all, which is where the second function, translate, comes in. The translate function, well, translates. It replaces one character with another, so instead of having a label or a header of item_price, it can be ITEM PRICE. For me, the latter is a lot more like what I expect when visiting a website. Accepting three parameters—the source string, the from string, and the to string—it returns a string consisting of one-for-one replacements of characters. I should cover a couple things before we use the translate function. The first of these is that in instances when the from string doesn’t contain a particular character, that character is copied unchanged. The second thing is that it is a good idea to verify that characters in the from string and characters in the to string are in the same position in their respective strings. Or, more simply stated, using a from string of qwerty and a to string of wertyu will result in a Caesar Cipher. And although a Caesar Cipher might have been state-of-theart in 40 B.C., I’m reasonably sure that it isn’t the result that you’ve hoped for. With that out of the way, let’s take a look at Listing 12-8, which is an XSL style sheet that creates a basic form.