RE: [xsl] Can exclude-result-prefixes alter the qualified name of an element?

Subject: RE: [xsl] Can exclude-result-prefixes alter the qualified name of an element?
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Fri, 28 Jan 2005 21:51:32 -0000
The answer to your subject line is NO. 

> 
> As an example, I might have as input:
> 
> 	<?xml version="1.0" ?>
> 	<i xmlns="input" xmlns:o="output">
> 	  <o:e/>
> 	</i>
> 
> and desired output:
> 
> 	<?xml version="1.0" ?>
> 	<o xmlns="output">
> 	  <e/>
> 	</o>
> 
> The transformation I came up with is:
> 
> 	<?xml version="1.0" ?>
> 	<xsl:stylesheet version="1.0"
> 	                xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
> 	                xmlns:i="input"
> 	                xmlns:o="output"
> 	                exclude-result-prefixes="i o"
> 	                >
> 	  <xsl:template match="i:i">
> 	    <o:o xmlns="output">
> 	      <xsl:apply-templates/>
> 	    </o:o>
> 	  </xsl:template>
> 
> 	  <xsl:template match="o:e">
> 	    <xsl:copy-of select="."/>
> 	  </xsl:template>
> 
> 	</xsl:stylesheet>

The rules here are:

(a) a literal result element copies all namespaces that are in scope in the
stylesheet, except for excluded namespaces (the XSLT namespace and those
listed in exclude-result-prefixes)

(b) xsl:copy-of (in XSLT 1.0) copies all inscope namespaces from the source
document, unconditionally.

(c) In (a) and (b), copying a namespace means copying both the prefix and
the URI.

(d) Additional namespace declarations MAY be generated by the serializer (or
in 2.0, the namespace fixup process) - the processor has some discretion in
this.
> 
> An earlier version did not have the namespace declaration on the
> literal <o:o> element, nor did it have the exclude-result-prefixes
> attribute. That earlier version gave me a valid and correct result[*]:
> 
> 	<?xml version="1.0"?>
> 	<o:o xmlns:o="output" xmlns:i="input">
> 	  <o:e/>
> 	</o:o>

I don't think this is correct. In the input, the <o:e> element has an
inscope namespace with prefix="", URI="input". This namespace node should
have been copied, and there is nothing you can do in your stylesheet to
prevent it. (XSLT 2.0 provides an option on xsl:copy-of). 
> 
> But this is not as clean as what I set out for originally. It's got an
> extraneous namespace declaration and unnecessary use of a prefix for
> what could be the default namespace.
> 
> If I take the stylesheet as above, but using just a value of "o" for
> exclude-result-prefixes, I get quite close to the desired result:
> 
> 	<?xml version="1.0"?>
> 	<o xmlns="output" xmlns:i="input">
> 	  <e/>
> 	</o>

Again, I don't think this is correct. In the input, the <o:e> element has an
inscope namespace with prefix="o", URI="output". This namespace node should
have been copied, and there is nothing you can do in your stylesheet to
prevent it.
> 
> That's perfect except for one extraneous namespace declaration. And
> the XSLT specification explicitly says that getting rid of something
> like this is just what exclude-result-prefixes is designed for. But
> when I use exclude-result-prefixes="i o", (in other words, using the
> stylesheet exactly as quoted above), I get the following unexpected
> result:
> 
> 	<?xml version="1.0"?>
> 	<o xmlns="output">
> 	  <e xmlns="input"/>
> 	</o>
> 

The previous results looked non-conformant but liveable-with, this one looks
disastrous.

Michael Kay
http://www.saxonica.com/

Current Thread