Re: [xsl] Why doesn't this simple XSLT (Identity transform) work?

Subject: Re: [xsl] Why doesn't this simple XSLT (Identity transform) work?
From: Wendell Piez <wapiez@xxxxxxxxxxxxxxxx>
Date: Wed, 02 Dec 2009 11:12:46 -0500

At 09:19 AM 12/2/2009, Ken wrote:
At 2009-12-01 21:46 -0500, ohaya@xxxxxxx wrote:
the problem was that the match I was using was not matching anything, so that xsl:template was not "catching", and the reason for not matching was because of the namespace.

Is that right?


At 2009-12-01 21:48 -0500, ohaya@xxxxxxx wrote:
Also, I think that what was 'throwing me off' was that the "sig:" namespace was implicit. That was why I was using just "Signature" instead of "sig:Signature".

That it was not implicit was the problem. And even if you had declared the default namespace in your stylesheet it still would not have worked, because in an XPath address in XSLT an element without a prefix is assumed to be in no namespace (note in XSLT 2 there is an option to declare the default namespace to use for elements in XPath addresses).

So, one has to associate the desired input namespace with a prefix to use in the stylesheet, regardless of whether the input file is or is not using a prefix for namespaces.

In other words, if the element in the input document is in a namespace, it must be matched with a name in the same namespace, and in XSLT there are only two ways to do this. First, the namespace may be made explicit in the match pattern (even if it is only implicit elsewhere), or second, in XSLT 2.0 a top-level declaration may be used to bind unprefixed names in XPath expressions, throughout the stylesheet, to a namespace (a considerable convenience). Note that only the first option is available in XSLT 1.0.

Binding unprefixed names to a namespace in the stylesheet in the usual way (with a namespace declaration) does not do this, since while it affects unprefixed names of XML elements in the stylesheet (as it is supposed to), it does not affect unprefixed names inside XPath expressions, which are only inside attribute values in the XSLT-as-XML -- that is, as "namespaces in content".

An illustration:

<illustration xmlns="data:,illustration">
  <element attribute="value"/>

While the 'illustration' and 'element' elements are in the declared (unprefixed) namespace, there's nothing in XML that says the value "value" should be modified in any way. This is exactly analogous to:

<xsl:template xmlns="data:,illustration" match="element">

(Nor would it be wise for XSLT to specify this for its XPath expressions, if you want to think about the case where a stylesheet needs to work with elements in different namespaces, either matching them or generating them, while any or all of them may appear unprefixed in the data.)

This is a very common gotcha for beginners or sometime users, since it becomes relevant as soon as namespaces come into play, and it's somewhat counterintuitive until you wrap your head around all of it -- both how namespaces work, and how XSLT stylesheets are XML documents and follow the rules thereof.

Only then does it make sense: the stylesheet works only if the names are the same, but to be the same, they have to look different.


Wendell Piez                            mailto:wapiez@xxxxxxxxxxxxxxxx
Mulberry Technologies, Inc.      
17 West Jefferson Street                    Direct Phone: 301/315-9635
Suite 207                                          Phone: 301/315-9631
Rockville, MD  20850                                 Fax: 301/315-8285
  Mulberry Technologies: A Consultancy Specializing in SGML and XML

Current Thread