views:

108

answers:

2

Refer to: http://stackoverflow.com/questions/1613454/retrieving-one-element-and-filter-by-another

In the above linked posting, I don't understand why the two template blocks don't get executed upon in the incoming XML at the same time. As far I can can see, the XSL risks the second template executing for every Document element whether it is called with apply-templates or not.

Could someone explain this to my stifled brain, please?

Thanks,

Matt.

+1  A: 

The template matching the root node <xsl:template match="/"> is the starting point for the transform and controls what happens from that point forward.

If the template for the root node did not call an apply-templates, then you would only get the output described within that template for the root node.

However, because it does call apply-templates, it tells the processor to execute whatever template rules that match the content it encounters. The xpath expression given in the @select happens to be Problems/Problem/Description, which limits the content in which the processor will apply template rules for to the Description elements.

So, since the XSLT has a template defined for Description elements (<xsl:template match="Description"> ), that template is triggered for each Description element that it encounters.

Mads Hansen
So, I am to take it that the document only starts executing at the template which matches the root of the document, with following templates only being executed when directed to by the XSL instructions, because they don't match the root...?
Matt W
Yes, the root node template essentially means the very beginning of the document(even before the document element, to include comments and processing instructions) and there can only be one root node template. You can determine what to do from there. If you just call apply-templates without a select, then it would go in document order looking for template matches.
Mads Hansen
+1  A: 

Mads is right that one template matches just the root xml element, and one matches a specific element (Problems/Problem/Description). So, the two are operating on different elements. However, is your question more general? Is it why aren't two xsl:templates that could both match a particular XML element executed against it? In other words, why wouldn't both the template that matches "node()" and the the one that matches "Problems/Problem/Description" run against the same Problems/Problem/Description XML element?

If so, then there's a key XSLT concept you're missing, priority. It's similar to order of operations that you learned in algebra (division, multiplication, subtraction, addition). In XSLT it works like this. For any given XML element, the default behavior is to process it once and only once. It's the job of the XSLT engine to determine all the templates that could act against a particilar XML element and find the most specific one and only apply that template.

How specificity is determined is a bit complicated, but in this example, it' simple. One template matches any nodes (node()), and the other matches a specific, named, node. So, the specifically named node wins.

For the full rules on priority, see section 5.5 of the XSLT spec at W3C. http://www.w3.org/TR/xslt

Adam J.R. Erickson