xsl-list
[Top] [All Lists]

RE: Namespaces and template matching

2002-11-08 12:21:09
Dave,

Thank you.  Your code worked exactly the way I wanted it to and I don't
see any code like this in Dave Pawson's FAQ.  You have been a tremendous
help.  Thanks again.

Regards,
Dave

-----Original Message-----
From: David N Bertoni/Cambridge/IBM 
[mailto:david_n_bertoni(_at_)us(_dot_)ibm(_dot_)com]
Sent: Thursday, November 07, 2002 9:19 PM
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: Re: [xsl] Namespaces and template matching






I am struggling with doing a template match when namespaces are
involved.

I have the following stylesheet which renames any 'x' 
element to 'y':

<?xml version='1.0' encoding='UTF-8'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
version="1.0">
   <xsl:template match="x">
      <xsl:element name="y">
         <xsl:apply-templates select="@*"/>
         <xsl:apply-templates/>
      </xsl:element>
   </xsl:template>
   <xsl:template match="@*|node()">
      <xsl:copy>
         <xsl:apply-templates select="@*"/>
         <xsl:apply-templates/>
      </xsl:copy>
   </xsl:template>
</xsl:stylesheet>


...


<?xml version="1.0" encoding="UTF-8"?>
<a>
   <x a="1" b="2" c="3" d="4" />
</a>


...


<?xml version="1.0" encoding="UTF-8"?>
<a xmlns="b">
   <x a="1" b="2" c="3" d="4" />
</a>

I'm sure this is a FAQ.  You're matching elements named "x" 
which have a
null namespace URI. Your second document contains an element x, but,
because it has no prefix, and there's a default namespace, 
it's namespace
URI is "b", so the template doesn't match.  However, the 
second template
matches (which defines an identity transformation), so the document is
copied.

If you want to match "x" elements with a namespace URI of 
"b", you should
define a template that matches them:

<?xml version='1.0' encoding='UTF-8'?>
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
  xmlns:foo="b"
  version="1.0">

   <xsl:template match="foo:x">
      <xsl:element name="y">
         <xsl:apply-templates select="@*"/>
         <xsl:apply-templates/>
      </xsl:element>
   </xsl:template>

...

If you want to match all elements with a local name of "x", 
you could do
the following:

   <xsl:template match="*[local-name() = 'x']">
      <xsl:element name="y" namespace="{namespace-uri()}">
         <xsl:apply-templates select="@*"/>
         <xsl:apply-templates/>
      </xsl:element>
   </xsl:template>

Note this template is also creating the "y" element in the 
same namespace
as the "x" element.  Whether or not that's appropriate is
application-specific, but if you leave it out, you're liable 
to get results
which might puzzle you.

Hope that helps...

Dave


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



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



<Prev in Thread] Current Thread [Next in Thread>