Subject: RE: 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/
|