This is the fourth segment of what was planned as an eight-part series on XML eXtensible Stylesheets Language Transformations, aka XSLT. The subject of this brief tutorial was supposed to be XSLT expressions, which employ variables and data types to seek out specific XSLT document elements and patterns to drive parsing of XML documents, and transform them into XML and other output formats. To some extent, this makes XSLT expressions...
the "transformation engine" inside XSLT, at least when input must be parsed, interpreted, reacted to, or manipulated in some form or fashion.
That said, complete coverage of XSLT expressions proves to be too big a subject to cover in a single tutorial tip. Thus, in this fourth of what now looks to nine total parts, we cover XSLT variables and data types used in expressions, and will dig into XSLT expressions themselves more deeply in our next tip. In the meantime, this tip digs you into XPath, which provides the foundation for XSLT expressions, and related variables and data types. Please read on and all this gibberish should start making some sense.
XSLT expressions are really XPath expressions (they're identical in syntax, structure and use). It's impossible to understand XSLT/Xpath expressions without also understanding XSLT/XPath variables and data types, so we take a tour through these topics here. Please consult any references in the XSLT tutorial series kick-off tip for additional information, discussion and examples on these topics as needed:
- Variables:As in many programming languages, XSLT scopes variables globally (spans an entire XSLT document and processing context) or locally (spans a single template body). If a variable declaration (which usually takes a form like <xsl:variable name="count" select="10"/>) occurs at the top level in an XSLT document (making it a child of xsl:stylesheet or other valid document elements) it's global; if a variable declaration occurs within a template body (making it a child of some xsl:template element) it's local.
|boolean||Logical variables may take values of either true or false, and those values result from invoking the functions true() and false(), respectively. Logical comparison operators «=» (equals) and «!=» (not equals) may be combined with logical operators «and» and «or» as well as the logical function not(). Boolean variables must always be either true or false; no null or undefined values are allowed.|
|number||A number is a double-precision 64-bit floating point number, defined in accordance with the IEEE 754 standard for floating point arithmetic. It's the same scheme used in Java. Valid operators include numerical comparison («<», «<=», «>», «>=»), numerical equality («=»,«!=»), unary minus («-»), multiplicative («*»,«div»,«mod»), additive («+»,«-»), numeric selection functions round(), ceil() and floor() to convert numbers to integers, and the function sum(), which totals numeric values of a set of nodes. The number() function converts any value to a number, string() and format-number() functions convert strings to numbers, and the boolean() function converts a number to a boolean value.|
|string||Any sequence of zero or more character values, where the possible alphabet maps to Unicode. String values are written as literals, enclosed either in single or double quotes, as in 'Bob' or "Alice" (this mechanism was designed to permit one type of quote to be treated as a literal, but because XPath expressions normally appear inside XML attributes, this doesn't work as intended; the other quote marks are already "taken"). Use character entities to reproduce necessary diacritical and syntax-sensitive characters in literals for best results. Compare strings using the «=», «!=» operators. A translate() function is available to convert between upper and lowercase alphabetical characters. The string-length function() returns the numeric length of XML characters included (not the total count of all 16-bit Unicode character codes).|
|node-set||A set of nodes in a source document tree, when multiple source document trees are in use, a node-set may combine nodes from more than one tree. Any node in a node-set may be any type of node, and different types can occur within the same node set. A node can appear only once in a set, but order of appearance is not significant (though nodes tend to be processed in "document order" reflecting their position in the source document tree). A single node takes the form of a node set with a single member.|
|tree||A value of type tree (formally called a result tree fragment) contains a root node, where the root may have zero or more children. As a fragment, a tree value does not necessarily correspond to a well-formed XML document and may thus violate well-formedness constraints in various ways (the root node may own text nodes directly; multiple element nodes may occur among its children). A tree value must still adhere to the rules that apply to an external parsed XML entity, meaning that all attributes must have unique names and all attribute values be properly represented, and so forth. XSLT supports only two operations on trees once they're constructed: They can be copied to the current destination tree (the result tree of some other tree variable using <xsl:copy-of> or the tree value may be converted to a string, resulting in concatenation of all text nodes in that tree. Trees are constructed by processing an <xsl:variable> declaration. The XSLT fragment shown in Listing 1 produces a specific tree instance, depicted in Listing 2.|
Listing 1: Defining a tree variable's value using <xsl:variable>
<xsl:variable name="txt"> The <xsl:element name="A"> <xsl:attribute name="attribute">avalue</xsl:attribute> Rain </xsl:element> <xsl:element name="B"/> InSpain </xsl:variable>
Listing 2: Tree graph for <xsl:variable> declaration (note: each node consists of three lines - the first identifies the node type, the second its name (a blank means no names is associated to the node) and the third its string value; an asterisk indicates the value is the concatenation of the string value of its children)
root * | ----------------------------------- | | | | text element element text A B The * * InSpain | ---------------- | | attribute text attribute avalue Rain
For the incurably curious, the string value that the <xsl:variable> declaration in Listing 1 produces is "TheRainInSpain." Notice also how nodes with no string values produce no output and how concatenation from children through parents permits the string to read from left to right, as graphed in Listing 2.
1st node in
text nodes in
This information sets the stage for our next tip, in which we'll dig into some details related to XSLT expressions and how they may be used. Please note that the information in Table 2 is reproduced directly from information on pages 80 and 81 of Michael Kay's outstanding book XSLT Programmer's Reference (Wrox, 2000, ISBN: 1861003129), still one of my very favorite resources on this subject.
About the author
Ed Tittel is a full-time writer and trainer whose interests include XML and development topics, along with IT Certification and information security topics. E-mail Ed with comments, questions, or suggested topics or tools for review.