A General Approach to Using XSLT
As I said earlier in the beginning of this chapter, both XSLT and XPath are very rich languages. XSLT, in particular, is so rich that there are several different approaches and paradigms for using it. Not all of them are appropriate for the types of transformations we're interested in. However, I need to mention them so that when you run across them in further XSLT study, you'll know what they are.
Literal Result Elements:
Both examples presented so far use this the style. It involves including the actual markup, text, and so on (that is, the "literal result"), in the body of the appropriate xsl:template so that it gets copied into the result tree. Text from an Element's Text Nodes and text from Attribute values is inserted in the result tree by xsl:value-of and, in some cases, xsl:apply-templates (which I'll discuss shortly). As we saw from the second example, an xsl:template's content can be a mix of literal results and XSLT Elements.
"Literal Result Element as Stylesheet":
This is the terminology used by the XSLT Recommendation. The authors of another Addison-Wesley title [Skonnard and Gudgin 2002] refer to it as an "exemplar-based" transformation (they're some of the same folks who like to say "transform" instead of "stylesheet"). In this model an XML document that isn't an XSLT stylesheet has Elements from the XSLT namespace embedded within it. When an XSLT processor processes a source document and uses this type of document as a stylesheet, it turns the XSLT Elements into the appropriate text and replaces them with the text. This design is roughly equivalent to having xsl:stylesheet as the root Element and a single xsl:template that matches on the source document root. There are several restrictions to using this approach, the most severe of which is that the whole document is a template and you can declare no other templates. This imposes several restrictions on how we process complex business documents, and except in a very few cases it is most likely not an appropriate model for us.
Creating Elements and Attributes with the xsl:element and xsl:attribute Elements:
There is an alternative to inserting literal text and markup like <HelloWorld>Howdy!</HelloWorld> in the content of an xsl:template. In the content of the xsl:template you can put xsl:element or xsl:attribute (with the appropriate Attributes and content) to create an Element or Attribute, respectively, in the result tree.
Of these three approaches I have a strong preference for the first, using literal result Elements. I do need to note that some caution must be taken in using this approach. Creating Elements and Attributes only with xsl:element and xsl:attribute should result in a well-formed XML document. However, if you get the literal markup wrong in a literal result Element, you can create an output XML document that is not well formed. However, the literal result approach, being less verbose and tedious, is much easier than the other options outlined above.
In addition to these general approaches, XSLT also supports two distinctly different programming paradigms.
Rule-based or logic (also called "declarative"):
This paradigm is oriented around a set of rules that don't necessarily have to be in any particular order. Logical rules are given a symbolic representation, and programs are merely sets of these rules. Logic programming focuses on specifying the desired results and leaves it to the machine to figure out how to produce them. Prolog is perhaps the best known example of a logic programming language.
Imperative (also called "procedural"):
This is perhaps the most commonly used and familiar programming paradigm. It focuses on algorithms and data structures. In contrast to logic programming, the imperative programming paradigm focuses primarily on telling the machine specifically how to produce a result. Most of our traditional programming languages are imperative, and even the object-oriented languages are largely imperative. Familiar examples include C, COBOL, and FORTRAN. Java and C++, even though object-oriented, are still based on the imperative model.
There is no escaping the fact that XSLT is predominately rule-based. For proof, we need look no further than the name "template rule" and the xsl:template content, which specifies a portion of the result tree rather than necessarily how to produce the result. However, XSLT does have some procedural features. It supports conditional processing with xsl:if and xsl:choose (a DOCASE). It also supports iterative processing with xsl:for-each. In addition, some of the ways in which templates can be invoked are more procedural than rule-based. We'll see examples of many of these later in the chapter.
My preference is to not stray very far from the basic nature of XSLT and to use the rule-based model wherever it will do the job. In some specific cases a procedural approach is appropriate, but I tend to stick with the general rule-based model. That is what I will present in this chapter.
XSLT uses XPath extensively, and we are now at the point where we need to discuss some XPath basics before we can get any further with XSLT.