Re: [xsl] removing namespaces

Subject: Re: [xsl] removing namespaces
From: Abel Braaksma <abel.online@xxxxxxxxx>
Date: Wed, 02 Apr 2008 01:35:01 +0200
Hi Garvin,

see my comments below.


Garvin Riensche wrote:
I should have written "tiding up namespaces" instead of "removing" as I don't want to loose them. I just want to clean them up.

Maybe I am wrong but I thought that if the "method" element has the namespace "http://new.element";, all child elements will belong to this namespace too. So there's no need to write the namespaces of the child elements to the output.

No. The method element has indeed the mentioned namespace. All child element will have the namespace that is bound as the default namespace, which, when not defined, is the default empty namespace. To emphasize this, the serializer puts xmlns="" on the main element, to make sure the child elements are in the default empty namespace.


To work with namespaces it is best practice to use the prefixes you formerly declared.


The namespaces are as you proposed defined in the stylesheet element on top of the stylesheet:


<xsl:stylesheet version="2.0"
    xmlns:srcml="http://srcml.de";
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
    xmlns:srcml-new="http://new.element";
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
    xmlns:meta="http://srcml.de/meta";>

Good, that's what I meant. Now, do not use the namespace attribute anymore in the xsl:element instruction. Instead, use the prefix you declared in the the xsl:stylesheet element. The name of xsl:element must contain a QName. The first part of a QName is the prefix of the namespace. This makes the namespace attribute (in your case) redundant.
...

I don't really understand why the namespaces show up in the elements although they are declared on top of the stylesheet.

They show up because you specifically declare them again (using the namespace attribute of xsl:element). Don't do that, use the prefix instead, and your problem goes away. Also, when the name of the element is a fixed name (i.e., does not come from a variable or XPath expression) then it is normally better and more readable to not use xsl:element at all but just use a literal result element (i.e., just write <method> or <myns:method> instead of <xsl:element name="method"> or <xsl:element name="myns:method">)


Also, in the case that your resulting document does not have a single root element (which is not allowed in XML but is allowed in XSLT output for various reasons) every "rooted" element must have all namespaces declared again and again. Once there's a single root element, the serializer can optimize by putting the namespaces there.

And I am wondering where the xmlns="" comes from. It would just look nicer if I could get rid of the namespaces in the elements. If I use the Syntax srcml-new:modifiers in the template instead of just "modifiers" there is still the complete srcml-new namespace definition in the output.

It seems to me that the redeclaration of the default namespace to an empty namespace (the default of XML + NS) is not necessary in your case, but I haven't seen enough of your code to justify that statement. The reason that a serializer will redeclare the default namespace to the empty namespace can be one of ambiguity, or because you ask him to. Again, removing all the extra namespaces in your code (xsl:element and xsl:attribute) will make your code cleaner and probably removes this redundant declaration too.

Note that over-declaration of your namespace means that your document is wrong. If your document is used for machine reading (i.e. further processing) and the namespaces are otherwise correct, then there's technically no necessity to remove the redundant namespaces (other then space, but space is cheap nowadays).

Cheers,
-- Abel Braaksma

Current Thread