Re: [xsl] namespace scope

Subject: Re: [xsl] namespace scope
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Thu, 2 May 2002 15:18:03 +0100
Hi Joeri,

> I am doing an XML to XML copy and need to add a few new elements.
> The copy is fine but why are my added elements outputted with 2
> xmlns attributes?
> An empty one and an our namespace. I have definined it at the top in
> xls:stylesheet.

In your stylesheet, you have declared the XSLT namespace and the NOL
namespace, neither of which is the default namespace (the namespace
associated with no prefix). Then you create an mutcode element using a
literal result element:

> XLST stylesheet looks like this

> <xsl:stylesheet version="1.0"
> xmlns:xsl="";
> xmlns:nol="">
> ...
> <xsl:template match="nol:offertelijn">
>   <xsl:copy>
>     ...
>     <xsl:choose>
>       <xsl:when test="nol:referteklant = ''">
>         <mutcode>NEW</mutcode>
>       </xsl:when>
>       <xsl:otherwise>
>         <mutcode>MOD</mutcode>
>       </xsl:otherwise>
>     </xsl:choose>

>   </xsl:copy>
> </xsl:template>

In the stylesheet, the mutcode element is in no namespace -- it
doesn't have a prefix, and you haven't declared a default namespace.
When a processor puts a literal result element in the result tree, it
maintains the namespace of that literal result element, so your result
contains a mutcode element in no namespace.

It also needs to make sure that the result element has the same
namespace declarations in scope that are in scope for the literal
result element. In your stylesheet, the NOL namespace is in scope,
declared with the prefix 'nol', so the mutcode element will also have
a NOL namespace associated with it.

Now, you're also copying elements from your source document. In the
source document, you have declared a default namespace:

> <?xml version="1.0"?>
> <root xmlns="">
> ...
>   <offertelijn>
>   ...
>   </offertelijn>
> </root>

When the processor copies the offertelijn element, for example, it
needs to create an offertelijn element in the NOL namespace, but with
no prefix.

When the processor *serializes* the document, it needs to do so in a
way such that the offertelijn element is in the NOL namespace but the
mutcode element is in no namespace. First, it creates the offertelijn
element in the NOL namespace:

  <offertelijn xmlns="">

then inside that it needs to add a mutcode element in no namespace.
The only way you can make an element be in no namespace is if it
doesn't have a prefix and there's no default namespace in the scope.
So the processor has to add a namespace declaration that resets the
default namespace to no namespace to the mutcode element. In addition,
it has to make sure that the mutcode element has a namespace in scope
with the prefix 'nol' mapped to the NOL namespace. So it adds the two
namespace declarations:

  <offertelijn xmlns="">
    <mutcode xmlns=""

That's why it's happening. I suspect that you want the mutcode element
to be in the NOL namespace. If that's the case, you should make the
default namespace in the stylesheet the NOL namespace, as follows:

<xsl:stylesheet version="1.0"

If you want to make sure that the xmlns:nol namespace declaration
doesn't appear in the output as well, then add a
exclude-result-prefixes attribute to the xsl:stylesheet element too:

<xsl:stylesheet version="1.0"



Jeni Tennison

 XSL-List info and archive:

Current Thread