Re: [xsl] namespace output problem

Subject: Re: [xsl] namespace output problem
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Mon, 5 Nov 2001 14:49:59 +0000
Jim (cutlass) wrote:
>> I can get the namespace declaration to appear on the updg:sync
>> element, but not on the ROOT element, unless I add a updg:ROOT
>> prefix to it (this breaks SQL Server).
>>
>> I've been through the FAQ looking for a solution, but can find
>> none. Is there a way of outputting what I want, while treating
>> xsl:output by method="xml"
>
> try replacing your literal element ROOT with xsl:element.
>
> <xsl:element name="ROOT"
> namespace="urn:schemas-microsoft-com:xml-updategrame">
>
> </xsl:element>
>
> this will output the default namespace to the one declared

Yes, it would add a default namespace declaration and it would place
the ROOT element in that namespace. But that's not what James was
after. The output James wanted was:

<textarea rows="30" cols="100" name="template">
  <ROOT xmlns:updg="urn:schemas-microsoft-com:xml-updategram">
    <updg:sync>
      <updg:before>
      </updg:before>
      <updg:after>
        <testData itemLink="http://www.abc.com/1"; itemTitle="weblog"/>
      </updg:after>
    </updg:sync>
  </ROOT>
</textarea>

Here, the ROOT element is in no namespace but it has a namespace node
with a name/prefix of 'updg' and a value/URI of
'urn:schemas-microsoft-com:xml-updategram'.

Actually, looking at the stylesheet, the only reason that the ROOT
element doesn't have this namespace node on it is because James has
specifically excluded it by adding a exclude-result-prefixes attribute
to the xsl:stylesheet element:

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                xmlns:updg="urn:schemas-microsoft-com:xml-updategram"
                exclude-result-prefixes="updg">

<xsl:template match="/">
  ...
  <textarea rows="30" cols="100" name="template">
    <ROOT>
      <xsl:apply-templates select="//item"/>
    </ROOT>
  </textarea>
  ...
</xsl:template>
...
</xsl:stylesheet>

The updg namespace declaration on the xsl:stylesheet element means
that all literal result elements have a updg namespace node; the
exclude-result-prefixes attribute removes these namespace nodes from
the result tree (unless they're absolutely required).

I think that the best solution is to remove the updg namespace
declaration (and the exclude-result-prefixes attribute) from the
xsl:stylesheet element, and insert instead firstly on the ROOT literal
result element, and secondly in the xsl:template that's generating the
elements that are in the updg namespace, so that their prefixes can be
understood:

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

<xsl:template match="/">
  ...
  <textarea rows="30" cols="100" name="template">
    <ROOT xmlns:updg="urn:schemas-microsoft-com:xml-updategram">
      <xsl:apply-templates select="//item"/>
    </ROOT>
  </textarea>
  ...
</xsl:template>

<xsl:template match="item">
  <updg:sync xmlns:updg="urn:schemas-microsoft-com:xml-updategram">
    ...
  </updg:sync>
</xsl:template>

</xsl:stylesheet>

This should give the required result (although as David C. will no
doubt point out, it should make absolutely no difference to the way
that the result is processed - if it does then the application
processing the XML is not namespace-aware, and it should be replaced
by one that is, or James should get the bug fixed).

Cheers,

Jeni

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


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


Current Thread