Meaning of “context” in regard to parameters of a calling template

浪尽此生 提交于 2019-12-04 10:16:13

Excellent question, well asked.

The behavior you expect would be natural in a language with dynamic scope. But XSLT uses lexical scope for variables, not dynamic scope.

You ask Now, what does "context" actually mean in XSLT, or more precisely, is a parameter considered part of the context or not?

Short answer: Yes, the parameter is part of the static context, for the expressions in its scope (and its absence is a fact about the static context of expressions elsewhere in the stylesheet); its value is part of the dynamic context for expressions in its scope. And (crucially) the xsl:call-template instruction does affect the context in which expressions are evaluated.

Longer answer: The specifics are to be found in the XSLT 2.0 spec. In section 2.5 the spec tells us that the context is divided into two parts: the static context and the dynamic context. Section 5.4 provides full details; section 5.4.1 lists "in-scope variables" as one component of the static context.

The scope rules for variables are given in section 9.7. The key bit is this:

A local variable binding element is visible for all following siblings and their descendants, with two exceptions: it is not visible in any region where it is shadowed by another variable binding, and it is not visible within the subtree rooted at an xsl:fallback instruction that is a sibling of the variable binding element.

The apparent contradiction you have run into relies crucially on the premise that "calling a template does not affect the context". This premise is not in fact correct, despite the fact that you have it on very good authority.

In section 10.1, the spec says that "the xsl:call-template instruction does not change the focus." It does not say that the instruction leave the context unaffected.

In the passage you quote from Michael Kay's book, I believe the term "context" is perhaps best taken as short for "context item", or perhaps "dynamic context". Even on that reading the sentence is not quite correct: because the dynamic variables component of the context differs, the dynamic context in the called template is not exactly the same as in the calling template. I think you have to cut MK some slack here: the paragraph in question is essentially unchanged from the XSLT 1.0 version of his book, and in XSLT 1.0 there is no explicit representation, in the discussion of context, of the dynamic binding of variables and parameters to names. But I think it's fair to say you've found something in the book MK might wish to change in the next revision.

http://www.w3.org/TR/xslt20/#static-context

The in-scope variables are defined by the variable binding elements that are in scope for the containing element (see 9 Variables and Parameters).

http://www.w3.org/TR/xslt20/#dt-variable-binding-element

The two elements xsl:variable and xsl:param are referred to as variable-binding elements

So, before you can use variables you have to bind them so they are available in the static context, else your XSLT program won't compile.


Parameters are in-scope only if you bind them. Why? Because it was designed that way.

The selected <xsl:template> is evaluated with no change to the context: it uses the same context item, context position, and context size as the calling template

The above statement is not 100% accurate. Using xsl:call-template keeps some of the dynamic context, such as context item, context position and context size, but it changes the variable values, which are taken from the in-scope variables of the static context. Every XPath expression has a static and dynamic context. In XSLT, the static context of an expression depends on the containing and enclosing elements.


XPath about focus:

The first three components of the dynamic context (context item, context position, and context size) are called the focus of the expression. The focus enables the processor to keep track of which items are being processed by the expression.

XSLT about focus:

When a sequence constructor is evaluated, the processor keeps track of which items are being processed by means of a set of implicit variables referred to collectively as the focus.

When you call xsl:call-template you are evaluating a sequence constructor. Because, unlike xsl:apply-templates and xsl:for-each, xsl:call-template does not change the items that are being processed, there's no change in focus.

However, the sequence constructor you are evaluating is a different template, and because templates are not nested in XSLT, XPath expressions used inside a template have different in-scope variables available than expressions used in another template. This is not an issue when you use xsl:for-each, which changes the focus but keeps the in-scope variables.

In XSLT, the static context of an expression depends on the containing and enclosing elements.

I'm afraid the paragraph you cite from XSLT 2.0 Prog Ref is less than accurate; it's using "context" as a shortcut for "dynamic context". It's a hazard when writing a book like this that if you're too precise and pedantic, it becomes as hard to read as the actual language spec, whereas if you cut corners, those who seek precision may be misled. The key thing here is that variable references can only refer to variables that are (statically) in scope. The static context for a called template (which defines which variables are in scope) is of course completely different from the static context of the call-template instruction.

You need to distinguish context and focus: http://www.w3.org/TR/xslt20/#dt-focus. When you use call-template, the focus does not change, see http://www.w3.org/TR/xslt20/#element-call-template which says "Unlike xsl:apply-templates, the xsl:call-template instruction does not change the focus.".

Calling another template does not change the context; however it does change the scope. You are not in the calling template anymore, therefore variables declared in the calling template do not apply in the current one.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!