Re: [xsl] XSL and Namespaces

Subject: Re: [xsl] XSL and Namespaces
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Thu, 8 Mar 2001 15:45:43 +0000
Hi Olivier,

>  - This is the XSL file:
> <xsl:stylesheet version='1.0'
> xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
>         <xsl:template match="/Schema">
>                 <xsl:copy>
>                         <xsl:attribute name="xmlns">
>                                 <xsl:value-of select="@xmlns" />
>                         </xsl:attribute>
>                         <xsl:attribute name="xmlns:dt">
>                                 <xsl:value-of select="@xmlns:dt" />
>                         </xsl:attribute>
>                         <xsl:attribute name="xmlns:sql">
>                                 <xsl:value-of select="@xmlns:sql" />
>                         </xsl:attribute>
>                         <xsl:apply-templates />
>                 </xsl:copy>
>         </xsl:template>
> </xsl:stylesheet>

OK. For a start, namespace declarations (attributes that start with
xmlns) aren't counted as attributes in the XSLT world view.  Instead,
every element has a number of namespace nodes on it - one for each of
the namespaces that the element is in scope for.  So in your example:

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
               xmlns:dt="urn:schemas-microsoft-com:datatypes"
               xmlns:sql="urn:schemas-microsoft-com:xml-sql">           
</Schema>

The Schema element has three namespace nodes on it: one called nothing
(the empty string) which has a value of
'urn:schemas-microsoft-com:xml-data', one called 'dt' which has a
value of 'urn:schemas-microsoft-com:datatypes', and one called 'sql'
with a value of 'urn:schemas-microsoft-com:xml-sql'.

When you copy an element using XSLT, then all the namespace nodes on
that element are copied as well, so you don't have to worry about
copying all the declarations. The processor will output a namespace
declaration if it needs to - often it will only add them if there
isn't already a namespace declaration for that namespace in scope.

The reason that you got nothing when you tried the above template is
that the match pattern for the template matches 'Schema' elements *in
the null namespace*, whereas the 'Schema' element in your source
document is in the XML Data namespace. If you want to match the Schema
element in the XML Data namespace, then you need to declare the XML
Data namespace in your stylesheet. It has to have a prefix. So you
could just use:

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                xmlns:xd="urn:schemas-microsoft-com:xml-data">

<xsl:template match="/xd:Schema">
   <xsl:copy>
      <xsl:apply-templates />
   </xsl:copy>
</xsl:template>
                
</xsl:stylesheet>

>  - If I remove the namespaces from the source file:
> <?xml version="1.0" ?>
> <Schema>                
> </Schema>
>
> - I have the following result:
> <?xml version="1.0" encoding="UTF-8"?>
> <Schema xmlns:dt="" xmlns:sql="">               
> </Schema>

Which processor are you using?  XSLT processors shouldn't output
attributes that begin with xmlns unless they're actually namespace
declarations (which these aren't).  So that looks like a processor
bug.

I hope that helps,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/



 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread