Read XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition Online
Authors: Michael Kay
This style of processing is called
push
processing. It is driven by the
In this description I occasionally talk of instructions writing to the result tree. This is how the process was described in XSLT 1.0, and it accounts for the name push. It's a convenient way to think about what's going on. Technically, as we have seen, instructions don't write to the result tree; they are evaluated to produce a sequence (usually a sequence of nodes, but occasionally atomic values) and this sequence is then used by the calling instruction, often to construct the children of a new element. The importance of this model is that in XSLT 2.0, there are some situations in which the result of a sequence constructor is not used directly to build part of a result tree, but can be used in some other way, for example as the result of an XPath function call.
In such situations it is possible for an XPath expression to encounter nodes such as attributes and text nodes that have no parent, because they have not yet been attached to a result tree.
Controlling Which Nodes to Process
Simple push processing works very well when the data in the output is to have the same structure and sequence as the data in the input, and all we want to do is add or remove a few tags or perform other simple editing of values as we go along.
In the previous example, it wouldn't work so well if the properties of each book were less predictable, for example if some of the books had no price, or if the title and author could appear in either order. In this case the HTML table that we generated wouldn't be nicely arranged in columns any more, because generating a new cell for each property we encounter is not necessarily the right thing to do.
In such circumstances, there are two choices:
Let's try the first option.
Example: Controlling the Sequence of Processing
We can gain greater control over
which
nodes are to be processed by changing the
books.xsl
, as follows:
Instead of selecting all child elements and finding the appropriate template rule for each one, this now explicitly selects first the
This will still work, and it's more robust than our previous attempt, but it will still produce a ragged table if there are any
The comma operator used in the expression
select=“author, title, price”
is new in XPath 2.0. It simply concatenates several sequences (which might be single items, but could also be empty, or contain multiple items) into a single sequence, in the order specified.
As we want a regular structure in the output and because we know a lot about the structure of the source document, we'd probably be better off in this situation defining all the processing in the
Example: Selecting Nodes Explicitly
We can gain greater control over
how
nodes are to be processed by writing the
Some people call this
pull
processing, because instead of the template pushing nodes out of the door to be picked up by another template, it is pulling the nodes in and handling them itself.
The pattern-matching (or push) style of processing is the most characteristic feature of XSLT, and it works very well in applications where it makes sense to describe the handling of each type of node in the source document independently. However, there are many other techniques available, all of which are equally valuable. From within a template rule that is processing one particular node, the main alternatives if you want access to information in other nodes are as follows:
Further discussion of the different approaches to writing a stylesheet is included in Chapter 17,
Stylesheet Design Patterns
.
Modes
Sometimes you want to process the same node in the source tree more than once, in different ways. The classic example is to produce a table of contents. When generating the table of contents, you want to handle all the section headings in one way, and when producing the body of the document, you want to handle them in a different way.
One way around this problem is to use push processing on one of these passes through the data, and pull processing on all the other occasions. However, this could be very constraining. Instead, you can define different modes of processing, one for each pass through the data. You can name the mode of processing when you call
Then the selected template rule might be one defined as:
…
Further details of how to use modes are in Chapter 6, page 242 and a real-life case study showing how to use them to generate a table of contents is in Chapter 18, page 1019.
Built-In Template Rules
What happens when
A
built-in template rule
is invoked.
There is a built-in template rule for each kind of node. The built-in rules work as follows.
Node Kind | Built-In Template Rule |
Document | Call |
Element | Call |
Attribute | Copy the attribute value to the result tree, as text—not as an attribute node. |
Text | Copy the text to the result tree. |
Comment | Do nothing. |
Processing instruction | Do nothing. |
Namespace | Do nothing. |
The built-in template rules will only be invoked if there is no rule that matches the node anywhere in the stylesheet.
There is no way to override the built-in template for namespace nodes, because there is no pattern that will match a namespace node. If you call
Conflict Resolution Policy
Conversely, what happens when there is more than one template rule whose pattern matches a particular node? As I mentioned earlier, the conflict resolution policy comes into play.
This works as follows: