web analytics

Understanding XSLT Templates Priorities

Options

codeling 1595 - 6639
@2016-12-18 10:38:17

It is possible for a node in a source document to match more than one template rule. When this happens, only one template rule is evaluated for the node. The template rule to be used is determined as follows:

  1. First, only the matching template rule or rules with the highest import precedence are considered. Other matching template rules with lower precedence are eliminated from consideration.

  2. Next, of the remaining matching rules, only those with the highest priority are considered. Other matching template rules with lower priority are eliminated from consideration. The priority of a template rule is specified by the priority attribute on the xsl:template declaration.

    [ERR XTSE0530] The value of this attribute must conform to the rules for the xs:decimal type defined in [XML Schema Part 2]. Negative values are permitted..

    [Definition: If no priority attribute is specified on the xsl:template element, a default priority is computed, based on the syntax of the pattern supplied in the match attribute.] The rules are as follows:

    • If the pattern contains multiple alternatives separated by | , then the template rule is treated equivalently to a set of template rules, one for each alternative. However, it is not an error if a node matches more than one of the alternatives.

    • If the pattern has the form /, then the priority is −0.5.

    • If the pattern has the form of a QName optionally preceded by a PatternAxis or has the form processing-instruction( StringLiteralXP) or processing-instruction(NCName Names) optionally preceded by a PatternAxis, then the priority is 0.

    • If the pattern has the form of an ElementTestXP or AttributeTestXP, optionally preceded by a PatternAxis, then the priority is as shown in the table below. In this table, the symbols E, A, and T represent an arbitrary element name, attribute name, and type name respectively, while the symbol * represents itself. The presence or absence of the symbol ? following a type name does not affect the priority.

      Format Priority Notes
      element() −0.5 (equivalent to *)
      element(*) −0.5 (equivalent to *)
      attribute() −0.5 (equivalent to @*)
      attribute(*) −0.5 (equivalent to @*)
      element(E) 0 (equivalent to E)
      element(*,T) 0 (matches by type only)
      attribute(A) 0 (equivalent to @A)
      attribute(*,T) 0 (matches by type only)
      element(E,T) 0.25 (matches by name and type)
      schema-element(E) 0.25 (matches by substitution group and type)
      attribute(A,T) 0.25 (matches by name and type)
      schema-attribute(A) 0.25 (matches by name and type)
    • If the pattern has the form of a DocumentTestXP, then if it includes no ElementTestXP or SchemaElementTestXP the priority is −0.5. If it does include an ElementTestXP or SchemaElementTestXP, then the priority is the same as the priority of that ElementTestXP or SchemaElementTestXP, computed according to the table above.

    • If the pattern has the form NCName Names:* or *:NCName Names, optionally preceded by a PatternAxis, then the priority is −0.25.

    • If the pattern is any other NodeTest XP, optionally preceded by a PatternAxis, then the priority is −0.5.

    • Otherwise, the priority is 0.5.

    Note:

    In many cases this means that highly selective patterns have higher priority than less selective patterns. The most common kind of pattern (a pattern that tests for a node of a particular kind, with a particular expanded-QName or a particular type) has priority 0. The next less specific kind of pattern (a pattern that tests for a node of a particular kind and an expanded-QName with a particular namespace URI) has priority −0.25. Patterns less specific than this (patterns that just test for nodes of a given kind) have priority −0.5. Patterns that specify both the name and the required type have a priority of +0.25, putting them above patterns that only specify the name or the type. Patterns more specific than this, for example patterns that include predicates or that specify the ancestry of the required node, have priority 0.5.

    However, it is not invariably true that a more selective pattern has higher priority than a less selective pattern. For example, the priority of the pattern node()[self::*] is higher than that of the pattern salary. Similarly, the patterns attribute(*, xs:decimal) and attribute(*, xs:short) have the same priority, despite the fact that the latter pattern matches a subset of the nodes matched by the former. Therefore, to achieve clarity in a stylesheet it is good practice to allocate explicit priorities.

@2016-12-18 10:40:56

In general, the following rules apply in order (e.g. a template eliminated from consideration due to lower import precedence is eliminated permanently, regardless of its priority):

  1. Imported templates have lower precedence than templates in the primary stylesheet
  2. Templates with a higher value in their priority attribute have higher precedence
  3. Templates without a priority attribute are assigned a default priority. Templates with more specific patterns take precedence.
  4. It's an error if the previous three steps leave more than one template in consideration, but XSLT processors can recover by defaulting to the last one in the file.

Here are some priority examples:

PATTERN PRIORITY
foo 0
processing-instruction(foo) 0
foo:* -0.25
* -0.5
node() -0.5
text() -0.5
comment() -0.5
processing-instruction() -0.5
foo/bar 0.5
foo/* 0.5
foo[bar] 0.5
*[*] 0.5
foo[bar] 0.5
*/* 0.5

Its a mistake to think that foo/* has a priority of -0.5. Only patterns consisting of *just* a NodeTest have priority of -0.5. As soon as you introduce filtering [] or composition /, that bumps the default priority up to 0.5 (because foo/* is more specific than foo or *).

 

Comments

You must Sign In to comment on this topic.


© 2024 Digcode.com