This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 30093 - [xslt30] Incorrect explanation of example pattern
Summary: [xslt30] Incorrect explanation of example pattern
Status: CLOSED FIXED
Alias: None
Product: XPath / XQuery / XSLT
Classification: Unclassified
Component: XSLT 3.0 (show other bugs)
Version: Proposed Recommendation
Hardware: PC All
: P2 normal
Target Milestone: ---
Assignee: Michael Kay
QA Contact: Mailing list for public feedback on specs from XSL and XML Query WGs
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-04-17 11:58 UTC by Michael Kay
Modified: 2017-05-31 09:27 UTC (History)
1 user (show)

See Also:


Attachments

Description Michael Kay 2017-04-17 11:58:50 UTC
In 5.5.1 we have an example pattern:

//para matches any para element that has a parent node.

This example is incorrect. The normative specification shows that this pattern matches any para element in a tree that is rooted at a document node.

(This error is also present in the XSLT 2.0 specification.)
Comment 1 Michael Kay 2017-05-04 17:43:07 UTC
The WG agreed the change, and I have changed the explanation of the example to say "//para matches any para element in a tree that is rooted at a document node".

The WG also asked the editor, for the record, to provide a technical explanation of why the example is incorrect.

The relevant rule for the semantics of this pattern is in ยง5.5.3 (The Meaning of a Pattern) and reads:

an item N matches a pattern P if the following applies, where EE is the equivalent expression to P: N is a node, and the result of evaluating the expression root(.)//(EE) with a singleton focus based on N is a sequence that includes the node N

So //para matches $N if the result of root($N)//(//para) contains N. This expression expands to

root($N)/
  descendant-or-self::node()/
  ( root(.) treat as document-node()/
    descendant-or-self::node()/
    child::para )

If $X is a root node then for every descendant $D of $X, root($D) will be $X. So this can be simplified to

root($N) treat as document-node()/
    descendant-or-self::node()/
    child::para

It is clear that 

(a) all nodes selected by this expression are elements named para

(b) in the case of a para for which root(.) is not a document node, the step (root(.) treat as document node) will fail with a dynamic error, and therefore the pattern will not match

(c) for every element E in a tree that is rooted at a document node, E is either a child of the document node, or a child of a descendant of the document node, and therefore the pattern selects EVERY element named para in such a tree.