[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Trouble with namespaces and running identity trans

Subject: Re: Trouble with namespaces and running identity transform on XHTML
From: Wendell Piez <wapiez@xxxxxxxxxxxxxxxx>
Date: Wed, 10 Mar 2004 11:36:11 -0500
xhtml trans
James,

On the test documents you provided yesterday, this will also work:

<xsl:template match="h:h1|h:h2|h1|h2">
<p>
   LOOK MA! <xsl:apply-templates select="@*|node()"/>
NO BRAINS!
</p>
</xsl:template>

(Quibble: you probably don't want to select "@*" here, unless you know what you're doing.)

Let's consider briefly why "h:h1 | h1" works as a match, and *[local-name()='h1']" works as a match, but neither "h:h1" nor "h1" work to match your four cases.

First off: the presence or absence of a DOCTYPE declaration will have no impact on how elements are matched. (When a DOCTYPE declaration is present and the parser validates the document before passing it to the XSLT engine, it can affect attribute values, for which a DTD can provide defaults; but it won't affect element matching.) So your four cases collapse into two.

The two cases hinge on whether a namespace declaration is present in your source:

<html xmlns="http://www.w3.org/1999/xhtml">

This basically says "the null [unprefixed] namespace is bound to the URI "http://www.w3.org/1999/xhtml" (or URL, or whatever parlance you prefer for that thingie). Accordingly, the complete name of any unprefixed name in this namespace's scope includes this URI. So an h1, for example, is "really" named "{http://www.w3.org/1999/xhtml}h1" (using a more-or-less random notation).

In order to match a namespaced element in a stylesheet, you must use a prefixed (qualified) name. This is why match="h:h1" works for you when you have a namespace declaration in the source file, and the "h:" prefix is bound in the stylesheet to the same namespace.

When there is no namespace declaration in the source file, however, the name is not qualified, so you need match="h1" in your stylesheet.

match="h:h1 | h1" catches both cases (again assuming the "h:" prefix is bound properly) in the same match pattern.

match="*[local-name()='h1'] also matches both elements, since the local name (the part of the name not including the namespace qualification) is the same, "h1".

I hope this helps. Namespaces can be tricky in XSLT.

Another way of dealing with this whole problem is to preprocess your input with a namespace normalizer -- an identity transform that outputs the input document with only its namespaces tweaked. Then all your inputs are the same, and your stylesheet needs to worry only about one or a known set of namespaces. Not that this is always a good idea (it rather goes against the whole point of namespaces).

I leave such a transform as an exercise for the reader. ;-)

Cheers,
Wendell
When there is no such


At 04:49 PM 3/9/2004, you wrote:
I've been working on a stylesheet to "massage" some
XHTML. One variation of a test stylesheet is here:

<xsl:transform
   xmlns:h="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="h:h1|h:h2">
<p>
   LOOK MA! <xsl:apply-templates select="@*|node()"/>
NO BRAINS!
</p>
</xsl:template>

<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

</xsl:transform>

I have four test documents that look something like
this:


<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="test_head_attr">
<title>Sample title</title>
</head>
<body id="test_body_attr">
<h1>Sample H1</h1>
<h2>Sample H2</h2>
<p>Body text
<br />
Other stuff.
<br /></p>
</body>
</html>

One of the four has both the DOCTYPE declaration and
an xmlns attribute, one has the DOCTYPE declaration
but no xmlns attribute, one has no DOCTYPE declaration
but an xmlns attribute, and one has neither a DOCTYPE
declaration nor an xmlns attribute. I'd *like* to get
a stylesheet that produced the same results on all
four test documents, but I'd settle for getting it to
work on the documents that set the xmlns attribute
explicitly in the html element and the documents with
the DOCTYPE declaration.

I've tried variants on this with the
exclude-result-prefixes attribute of xsl:stylesheet
and also tried messing with the xsl:namespace-alias
element, but can't seem to this to produce the same
output on both xsltproc and Saxon, and I keep getting
invalid output with attributes like xmlns="" or
xmlns:h="http://www.w3.org/1999/xhtml".

Any idea how to do this right?


======================================================================
Wendell Piez                            mailto:wapiez@xxxxxxxxxxxxxxxx
Mulberry Technologies, Inc.                http://www.mulberrytech.com
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
======================================================================


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



Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.