I like your question. You are very clear about what you have not yet understood. You just need to connect something. My recommendation is that you read “How XSLT Works,” in the chapter I wrote to accurately address the questions you ask. I would love to hear if this ties things together for you.
Less formally, I will take up the answer to each of your questions.
- In what order are the patterns executed and
- When they are executed, do they (a) match the original XML source or (b) the current XSLT output for that point?
At any given XSLT processing point, in a sense, there are two contexts that you identify as (a) and (b): where you are in the source tree and where you are in the result tree. Where you are in the source tree is called the current node. It can change and move throughout the source tree, as you select arbitrary sets of nodes for processing using XPath. However, conceptually, you never “jump” through the result tree in the same way. The XSLT processor builds it in an orderly manner; first, it creates the root node of the result tree; then adds children, creating the result in the order of the document (first in depth). [Your message motivates me to pick up my visualization software for XSLT experiments again ...]
The order of the template rules in the style sheet never matters. You cannot tell just by looking at the stylesheet in what order the template rules will be created, how many times the rule will be created, or even whether it will be created at all. ( match="/" is an exception, you can always know that it will be running.)
I assume that pattern # 1 will execute first. I don’t know why I suppose that this is only because it first appears in the document?
Nope. It could be called the first, even if you put it last in the document. The order of the template rules never matters (with the exception of the error condition, when you have more than one template rule with the same priority as the same node, even then it is not necessary for the developer, and you should never rely on this behavior). It is called first because the first thing that always happens when starting the XSLT processor is the virtual call <xsl:apply-templates select="/"/> . One virtual call creates an entire result tree. Nothing happens outside of it. You can customize or "customize" the behavior of this command by specifying template rules.
Is template # 2 running? It matches the node in the source XML, but by the time we get to this template (if it is the second one), the "firstName" node will not be in the output tree.
Template # 2 (or any other template rules) will never be run unless you have a call to <xsl:apply-templates/> somewhere in the match="/" rule. If you do not have them, then no template rules other than match="/" will be triggered. Think of it this way: in order for a template rule to be activated, it cannot just match the node value in the input. It should match the node you select for processing (using <xsl:apply-templates/> ). Conversely, it will continue to match node as many times as you want to process it.
Will [ match="/" template] pre-empt all other templates from execution, since there is nothing after the first template is completed?
This rule crowds out the rest, never including <xsl:apply-templates/> . There are many more nodes that can be processed in the source tree. They are always there, ripe for a choice; process each one as many times as you like. But the only way to handle them using template rules is to call <xsl:apply-templates/> .
At this point, I was worried with subsequent patterns that didn’t execute because the on nodes it uses did not appear on the output, but what about the opposite? Can you create a node "earlier", which template "later" can do something with?
Not that the earlier pattern creates a new node for processing; that the “earlier” template in turn processes more nodes from the source tree using the same instruction ( <xsl:apply-templates ). You can think of it as calling the same “function” recursively, with different parameters each time (nodes are processed according to the context and the select attribute).
In the end, you get a tree-like stack of recursive calls to the same "function" ( <xsl:apply-templates> ). And this tree structure is isomorphic to your actual result. Not everyone understands this or thought of it that way; because we don’t have effective visualization tools ... yet.
Template # 1 creates a new node called the "full name". Template No. 2 corresponds to the same node. Will template # 2 execute because the "fullName" node exists at the output by the time we get around template # 2?
Nope. The only way to make the processing chain is to explicitly configure it this way. Create a variable, for example $tempTree , that contains the new <fullName> element, and then process it like this <xsl:apply-templates select="$tempTree"> . To do this, in XSLT 1.0 you need to wrap the variable reference with an extension function (for example, exsl:node-set() ), but in XSLT 2.0 it will work the same way.
Whether you are processing nodes from the original source tree or to the temporary tree that you are creating, in any case you need to explicitly specify which nodes you want to process.
What we haven't looked at is how XSLT gets all its implicit behavior. You must also understand the built-in template rules. I constantly write stylesheets that do not even contain an explicit rule for the root of the node ( match="/" ). Instead, I rely on a built-in rule for root nodes (apply patterns to child elements), which is the same as a built-in rule for element nodes. That way, I can ignore large parts of the input, let the XSLT processor automatically cross it, and only when it encounters node, I wonder if I will do something special. Or I could write one rule that copies everything recursively (called an identity transformation), overriding it only where necessary, to make additional changes to the input. After you read “How XSLT Works,” your next appointment is to look at “identity transformation.”
I understand that I am deeply uninformed about the XSLT Zen. To date, my style sheets consisted of a template corresponding to the root of the node, then they are completely procedural from there. I'm tired of this. I would rather actually understand XSLT correctly, hence my question.
I greet you. Now it's time to take the “red pill": read "How XSLT Works"