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 29231 - [XT30] tests import-0001 and import-0002
Summary: [XT30] tests import-0001 and import-0002
Alias: None
Product: XPath / XQuery / XSLT
Classification: Unclassified
Component: XSLT 3.0 Test Suite (show other bugs)
Version: Last Call drafts
Hardware: PC Windows NT
: P2 normal
Target Milestone: ---
Assignee: Abel Braaksma
QA Contact: Mailing list for public feedback on specs from XSL and XML Query WGs
Depends on:
Reported: 2015-10-22 19:33 UTC by Abel Braaksma
Modified: 2016-02-16 14:32 UTC (History)
1 user (show)

See Also:


Description Abel Braaksma 2015-10-22 19:33:12 UTC
These tests expect the following output:

<out xmlns:xsl="">
  <xsl:transform a="1" />

But the XSLT in this test only sets the namespace on the the f:transform element (with a namespace alias). I don't think namespace fixup in this case allows the namespace to be moved to the root note (not sure), but I'm quite sure that the following is allowed output:

  <xsl:transform xmlns:xsl="" a="1" />

I will move forward and fix this, let me know if my assessment is in error.
Comment 1 Michael Kay 2015-10-22 20:55:40 UTC
Please hold fire on making changes here: I think the problem needs discussion.

At first glance, it seems XSLT 1.0 implied that namespace aliases applied to the URIs in namespace nodes, as well as the namespaces in the names of elements and attributes:

A namespace URI in the stylesheet tree that is being used to specify a namespace URI in the result tree is called a literal namespace URI. This applies to:

the namespace URI in the expanded-name of a literal result element in the stylesheet

the namespace URI in the expanded-name of an attribute specified on a literal result element in the stylesheet

the string-value of a namespace node on a literal result element in the stylesheet

In the 2.0 spec, the third item in the list has disappeared:

The effect is that when names in the namespace identified by the literal namespace URI are copied to the result tree, the namespace URI in the result tree will be the target namespace URI, instead of the literal namespace URI. This applies to:

the namespace URI in the expanded-QName of a literal result element in the stylesheet

the namespace URI in the expanded-QName of an attribute specified on a literal result element in the stylesheet

and 3.0 retains the 2.0 wording.

Was this change deliberate, and is it viable? Saxon appears to implement the 1.0 rule. The literal result element <out> has two in-scope namespaces, xsl and f, and it is applying aliasing to these namespaces as well as to the element and attribute names.

I would like to study this further before agreeing that the test case is wrong.
Comment 2 Michael Kay 2015-10-22 21:10:45 UTC
I think the test results are correct. The logic is as follows:

The <out> element has two namespace nodes: xsl=, and f=http://impincl32/ns.

The xsl:namespace-alias creates a mapping from the literal namespace URI http://impincl32/ns to the target namespace URI

The spec states:

When a literal result element is processed, its namespace nodes are handled as follows:

* A namespace node whose string value is a literal namespace URI is not copied to the result tree.
* A namespace node whose string value is a target namespace URI is copied to the result tree, whether or not the URI identifies an excluded namespace.

So the namespace node f=http://impincl32/ns is not copied to the result tree (under the first rule), but the namespace node xsl= is copied (under the second rule).
Comment 3 Abel Braaksma 2015-10-22 21:21:45 UTC
> I would like to study this further before agreeing that the test case is wrong.

Ok, thanks for holding it off, I will wait with submitting proposed changes (or, alternatively, both outcomes can be accepted).

So it boils down to:

<xsl:template match="/">
      <ns:b xmlns:ns="urn:other" />

whether this can be serialized after ns fixup to:

<a xmlns:ns="urn:other">
    <ns:b />

or that it must keep the namespace node "connected" to the <b> element. I think that:

1) if the namespace is declared before a certain LRE, it effectively becomes a namespace node on all descending elements (barring namespace redeclarations).

2) if the namespace node is declared only on the element itself, the namespace node springs into existence there and should not appear on ancestors as well.

3) if the namespace is an alias, the rules should apply (should apply?) to the alias, and be changed in-situ with the other namespace it is aliasing. That is to say, the namespace being aliased (here the XSL namespace) is *not* automatically in scope on the ancestors.

4) possibly, namespace fixup may bring the declaration closer to its use, if that doesn't invalidate required earlier namespace nodes.

Back to this case: On reconsideration, I think both outcomes are possible, because the f-namespace is declared as an ancestor of the LRE root, yet is only used in one place (but I have to admit I have always found the namespace fixup process rather fuzzy).
Comment 4 Abel Braaksma 2015-10-22 21:29:37 UTC
>  but the namespace node xsl= is copied 
> (under the second rule).

I didn't mean to say it is not being copied at all, it is just that I think it should be copied on the "xsl:transform" element, not necessarily on (all) its ancestors. But see my comment (it crossed yours), I think that both are possible. Am I wrong?
Comment 5 Abel Braaksma 2015-10-22 21:47:31 UTC
Under the section of 5.7.3 Namespace Fixup I found the following line:

XSLT 3.0 supports the creation of result trees that do not satisfy this constraint: the namespace fixup process does not add a namespace node to an element merely because its parent node in the result tree has such a namespace node.

This suggests that all the ancestors (may/must?) have this namespace node removed because it is not in use, and only when it is required to resolve the QName of the LRE element, it comes into play. I'm quite at a loss to whether this is required or implementation-defined, or even allowed behavior, though it seems reasonable to bring namespace declarations closer to their use.
Comment 6 Michael Kay 2015-10-22 22:35:11 UTC
I don't think namespace fixup plays any part in this. Namespace fixup is relevant only when an element or attribute has a name in a particular namespace but has no namespace node providing a binding for that namespace. Since <out> is in no namespace and has no attributes, there is no need for namespace fixup to do anything. In this case the namespace node is generated not because of the namespace fixup rules, but because of the namespace aliasing rules.

In the absence of the namespace alias: the <out> element would have two in-scope namespaces "xsl" and "f" (plus the trivial "xml" binding, of course). No namespace nodes (other than "xml") would be generated because the xsl namespace is implicitly an excluded namespace, while the f namespace is explicitly excluded. 

But the rules for namespace aliasing kick in before the rules for namespace exclusion, and the effect of these rules is unambiguously that the new <out> element has a namespace node for the xsl namespace.
Comment 7 Michael Kay 2015-10-22 22:47:47 UTC
Regarding comment #4, we only need to consider whether the xsl namespace node should be present on the <out> element. That's the key difference between the results expected by the test and the result you want. If we consider the LRE rules as applied to the <out> LRE, they tell us that the corresponding element in the result tree gets a namespace node for the xsl namespace, and nothing else is going to remove this.

Regarding comment #5, the note you cite says that the fact that a namespace node X=Y is present on a parent element does not necessarily mean that a namespace node for X will also be present on its children. That rule might (sometimes) mean that a namespace that's present on <out> isn't present on the children of <out>, but it can't cause any namespace nodes to be removed from the outermost element <out>.

There is no rule that namespace nodes can be removed from an element because they are not in use. Namespace fixup never removes namespace nodes, it only adds them.

Serialization eliminates redundant namespaces, but it will never eliminate a namespace from the outermost element because a namespace node on the outermost element can never be considered redundant. (A namespace is not redundant because it is unused, it can only be redundant because the same namespace appears on an ancestor element.)
Comment 8 Abel Braaksma 2015-10-23 13:02:10 UTC
Thanks for your extensive answers. I see now where I went wrong in my assessment. To prevent that I (or someone else) raises this again, I will update the test with a comment and point to this bug report. The test can stay as is (and I have to fix a bug in my implementation ;).
Comment 9 Abel Braaksma 2016-02-16 14:32:07 UTC
As discussed at F2F 2016 Prague there's was nothing else to be done here. Closed as WORKSFORME.