[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] XMLNS problem

Subject: Re: [xsl] XMLNS problem
From: Wendell Piez <wapiez@xxxxxxxxxxxxxxx>
Date: Wed, 13 Feb 2013 09:59:24 -0500


A further complication to this problem is that (chances are) you don't
want only the 'ead' element bound to namespace
"urn:isbn:1-931666-22-9", but indeed all its descendant elements in
the result tree.

If you express the namespace binding only in the template that
generates the 'ead' element, then elements produced by other templates
won't have the same binding, unless you do the same there.

That is, if you have:

<xsl:template match="ead">
   <ead xmlns="urn:isbn:1-931666-22-9"

<xsl:template match="did">
     <xsl:copy-of select="*"/>

you will get (assuming 'did' in the source has no namespace as I
suspect, if you are migrating your EAD from no-namespace to EAD 2002,
with a namespace):

<ead xmlns="urn:isbn:1-931666-22-9"
    <did xmlns=""> ... </did>

And this is not correct, pretty, or valid.

Of course, you want all elements in the result to be bound to the EAD
namespace, not just the top one.

The reason this happens is that the 'did' element in the stylesheet
doesn't inherit the namespace declaration from the 'ead' element in
the stylesheet (in a different template).

Solve this problem in either of two ways:

1. Generate all the elements using xsl:element and its @namespace
attribute, not just the 'ead' element (extending Mike's first
suggestion for all elements).

2. Less onerously, generate all the elements using literal results
(extending Mike's second suggestion) but declare the default namespace
xmlns="urn:isbn:1-931666-22-9" at the *top* of the stylesheet (the
xsl:stylesheet element) so it has global scope throughout the
stylesheet. (All elements in the stylesheet will inherit it.)

I have some namespace fixup utilities here:

You could also address your problem by running one of these, which
casts a document in no namespace into a namespace you designate.

Good luck,

On Tue, Feb 12, 2013 at 4:54 PM, Michael Kay <mike@xxxxxxxxxxxx> wrote:
> On 12/02/2013 21:35, Eric Harbeson wrote:
>> This is close, but it doesn't include the xmlns line, which appears to be
>> needed for it to validate correctly. The XSLT I have below seems like it
>> should do what I want, but it produces an error in the xsl:namespace
>> declaration.
>>      <xsl:template match="ead">
>>          <xsl:element name="ead">
>>              <xsl:namespace name="">urn:isbn:1-931666-22-9</xsl:namespace>
>>              <xsl:attribute
>> name="xsi:schemaLocation">urn:isbn:1-931666-22-9
>>                  http://www.loc.gov/ead/ead.xsd</xsl:attribute>
>>              <xsl:apply-templates/>
>>          </xsl:element>
>>      </xsl:template>
>> ...
>> </xsl:stylesheet>
> The xsl:element instruction creates the ead element in no-namespace, and you
> then attempt to add a namespace node that binds the default namespace to
> "urn:isbn:1-.....". Adding a namespace node to an existing element can't
> change the name(space) of the element, and is an error if it's inconsistent
> with the name of the element. You need to create the element in the right
> namespace to start with, and then the namespace node will be created for you
> automatically:
> <xsl:element name="ead" namespace="urn:isbn:1-931666-22-9">
> Alternatively, use a literal result element:
> <ead xmlns="urn:isbn:1-931666-22-9">
> though this doesn't give you quite such detailed control over namespaces.
> Michael Kay
> Saxonica

Wendell Piez | http://www.wendellpiez.com
XML | XSLT | electronic publishing
Eat Your Vegetables

Current Thread