- From: Michael Kay <mhk@mhk.me.uk>
- Date: Fri, 6 Feb 2004 10:18:23 -0000
- To: <public-qt-comments@w3.org>
The following comment was initially raised at: http://lists.w3.org/Archives/Member/w3c-xsl-wg/2003Oct/0122.html (member-only URL) (I think this comment slipped off the radar because we were too busy getting the Last Call draft published at the time. I have updated the note slightly to address the relationship of serialization and validation). We have changed the rules for namespace fixup so that when an element C is attached as a child of parent element P, it no longer automatically inherits the namespace nodes of P. We defined it this way for xsl:copy, and it works reasonably well in that case. The idea is that if you put your XML payload in a SOAP envelope and then extract it again, it hasn't been polluted with SOAP namespaces. This leads occasionally to a superfluous xmlns="" undeclaration, but that's liveable-with. More problematic is the situation with xsl:element. In a formal sense the rules here are exactly the same: we create a new element, in this case with no namespace nodes of its own unless we use xsl:namespace to create them. It then gets fixed up, which gives it namespace nodes for the element and attribute names, and then it gets attached to a new parent, at which point it acquires no additional namespace nodes. The effect of this is that if you are writing a stylesheet, and do: <xsl:template match="/"> <xsl:element name="xsl:stylesheet" namespace="http://www.w3.org/1999/XSL/Transform"> <xsl:namespace name="xs">http://www.w3.org/2001/XMLSchema</xsl:namespace> <xsl:element name="xsl:template"> <xsl:attribute name="match">attribute(*,xs:date)</xsl:attribute> </xsl:element> </xsl:element> </xsl:template> Then the "xs" namespace is in scope for the generated xsl:stylesheet element, but not for the generated xsl:template element, which means that the reference to xs:date is an error. At any rate, it will be an error if you serialize with undeclare-namespaces="yes"; but possibly also if you try to use the result tree as a stylesheet without serializing it, since the parser will look for an in-scope namespace node to resolve "xs:date" and won't find one. In a slightly modified example, one could show that QName-valued attributes would not pass validation. But this actually shows up a gap in our specs: we define validation formally in terms of a process of serializing the tree, then parsing to create an Infoset, and then validating the Infoset. But we don't say what options are chosen to do the validation. Currently XML Schema is only defined in terms of XML 1.0, so this would suggest serializing as XML 1.0, which has the fortuitous effect of propagating the namespace scope; but this doesn't seem a long-term solution. The problem is particularly acute for xsl:element because it doesn't inherit namespace nodes from its parents in the stylesheet either. The most obvious noticeable effect is a proliferation of xmlns="" undeclarations. If the parent element has a namespace node that binds the default prefix to some namespace, and if the child element has no namespace node for the default prefix, then the serializer is required to output xmlns="". In 1.0 you only get these if the child element actually uses the default namespace in its element name. We could say that this comes within the scope of undeclare-namespaces, but that's tricky, because the serializer can't easily tell whether the absence of a namespace node for the default namespace is significant or not. Technically there's probably no backwards incompatibility because XSLT 1.0 defined no way of accessing a result tree without serializing it, and serializing would always cause any namespace nodes (other than the default namespace perhaps) to be inherited by child elements because XML 1.0 didn't allow any other option. But I don't feel entirely comfortable about it. My first thought was to have different rules for xsl:copy-of and xsl:element but that doesn't work. The semantics describing how nodes are constructed are now completely separated from the semantics of how they are attached to a parent element, so the latter process can't depend on what instruction was used to create the element. One could potentially make it a property of the instruction that creates the parent element, so one could have an attribute propagate-namespaces="yes|no" on xsl:element, LREs, and xsl:copy. But I don't like that much - 99% of users would have no idea what it meant. The underlying problem seems to be that namespace undeclaration in XML 1.1 is a very positive signal that you don't want the namespace propagated. Because we use namespace nodes rather than declarations and undeclarations, we are relying on a negative signal: if you don't explicitly ask for the namespace at every level, you don't get it. It's hard to see how to change this without changing the model for namespace nodes, which is something I don't want to touch with a bargepole. So I think we have to make a binary choice: should namespace nodes automatically propagate from parents to children, or not? I'm a bit inclined at the moment to think that the low-risk approach is to propagate them, i.e. to revert to the previous specification. This would leave us without any way of forcing a namespace undeclaration to be output. Michael Kay
Received on Friday, 6 February 2004 05:17:55 UTC