Re: [xsl] Trouble with namespaces and running identity transform on XHTML

Subject: Re: [xsl] Trouble with namespaces and running identity transform on XHTML
From: "James J. Ramsey" <jjramsey_6x9eq42@xxxxxxxxx>
Date: Tue, 9 Mar 2004 17:15:38 -0800 (PST)
--- Kevin Jones <kjones@xxxxxxxxxxx> wrote:
> On Tuesday 09 March 2004 21:49, James J. Ramsey
> wrote:
> I keep
> getting
> > invalid output with attributes like xmlns="" or
> > xmlns:h="http://www.w3.org/1999/xhtml";.
> >
> 
> Hi James,
> 
> I would think the problem is that what you are
> thinking of as  
> "invalid output" is in fact correct for XSLT. The
> processors can 
> and will add namespace decalrations like xmlns="" if
> they are 
> needed to preserve the namespaces of the
> elements/attributes you 
> are generating and different processors do this in
> different 
> ways.

The idea is that both input and output should be valid
XHTML, so xmlns="" is definitely *not* helpful.

After posting to the list, I did manage to get a
solution that works, but I only have half an idea why.
Here's the working test stylesheet:

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

<xsl:output method="xml"/>

<xsl:template match="*[local-name() = 'h1']">
<p>
   <xsl:apply-templates select="@*" />
   LOOK MA! <xsl:apply-templates /> NO BRAINS!
</p>
</xsl:template>

<xsl:template match="*">
  <xsl:element name="{name()}">
    <xsl:apply-templates select="@*" />
    <xsl:apply-templates />
  </xsl:element>
</xsl:template>

<xsl:template match="@*">
   <xsl:attribute name="{name()}">
     <xsl:value-of select="."/>
   </xsl:attribute>
</xsl:template>

</xsl:transform>

This seems to work on any well-formed XHTML,
regardless of whether there is a DOCTYPE declaration
or an xmlns attribute with the value
"http://www.w3.org/1999/xhtml";. As far as I
understand, it transforms elements and attributes from
the source document, which could be either in the
"http://www.w3.org/1999/xhtml"; namespace or the null
namespace, into elements that by default are in the
default namespace declared in the xsl:transform
element. (AFAIK, since I used name() rather than
local-name() in the templates matching "*" and "@*", a
source document containing both XHTML and MathML
should pass through intact . . . I think.)

Here's what I don't get. If I use just "h1" in place
of "*[local-name() = 'h1']", then the stylesheet only
works for XHTML sources with *no* DOCTYPE or
explicitly set xmlns attribute. Judging from
http://www.dpawson.co.uk/xsl/sect2/N2281.html#d3008e295,
I know that if xmlns:h="http://www.w3.org/1999/xhtml";
were in xsl:transform, then the pattern "h:h1" would
match h1 elements in an XHTML source document with an
xmlns attribute set to "http://www.w3.org/1999/xhtml";.
Extrapolating from that, I would have concluded that
if 
if xmlns="http://www.w3.org/1999/xhtml"; were in
xsl:transform, then the pattern "h1" should match h1
elements in an XHTML source document with an xmlns
attribute set to "http://www.w3.org/1999/xhtml";, and
from that, concluded that if I replaced
"*[local-name() = 'h1']" with "h1" in the above
stylesheet, the stylesheet would then work only on a)
XHTML documents with the xmlns attribute set to
"http://www.w3.org/1999/xhtml"; and on b) XHTML
documents with DOCTYPE declarations--if the XSLT
processor actually makes use of the DTD declared in
the DOCTYPE declaration. Yet it works out the exact
opposite of what I expect.

I'm *still* confused.


__________________________________
Do you Yahoo!?
Yahoo! Search - Find what you?re looking for faster
http://search.yahoo.com

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


Current Thread