This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
RE: Matching nodes in the default namespace
- To: <xsl-list at mulberrytech dot com>
- Subject: RE: Matching nodes in the default namespace
- From: "Evan Lenz" <elenz at xyzfind dot com>
- Date: Thu, 28 Sep 2000 14:18:14 -0700
- Reply-To: xsl-list at mulberrytech dot com
You have to include a corresponding namespace declaration in your
stylesheet, binding it to a prefix of your choice. Then, in your match
patterns, include that prefix. Your stylesheet is written to match elements
that are not in a namespace. It matches nothing because all of the source
document's elements *are* in a namespace.
Below is the corrected stylesheet:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/TR/REC-html40"
xmlns:cat="http://www.example.com/catalog/">
<xsl:template match="/">
<html>
<title>Book catalog</title>
<body>
<table border="1">
<tr>
<th>Author</th>
<th>Title</th>
<th>Genre</th>
<th>Price</th>
<th>Pub Date</th>
<th>Description</th>
</tr>
<xsl:apply-templates select="*"/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="cat:catalog">
<xsl:apply-templates/>
</xsl:template>
<!-- Suppress individual children of <book>, and built-in
processing of all text nodes -->
<xsl:template match="*|text()"/>
<xsl:template match="cat:book">
<tr>
<td><xsl:value-of select="cat:author"/></td>
<td><cite><xsl:value-of select="cat:title"/></cite></td>
<td><xsl:value-of select="cat:genre"/></td>
<td><xsl:value-of select="cat:price"/></td>
<td><xsl:value-of select="cat:publish_date"/></td>
<td><xsl:value-of select="cat:description"/></td>
</tr>
</xsl:template>
</xsl:stylesheet>
If your stylesheet doesn't include a namespace declaration for a namespace
that's in the source document, there is no way you'll be able to explicitly
match nodes in that namespace (apart from using a wildcard, such as *).
Remember, whether the source document uses prefixes or not is completely
immaterial in XSLT. Forget about prefixes and think only about fully
qualified names which consist of a local name and a namespace URI. How that
fully-qualified name is represented, whether by a default namespace or a
namespace prefix, is immaterial.
Hope this helps!
Evan Lenz
elenz@xyzfind.com
http://www.xyzfind.com
XYZFind, the search engine *designed* for XML
Download our free beta software: http://www.xyzfind.com/beta
-----Original Message-----
From: owner-xsl-list@mulberrytech.com
[mailto:owner-xsl-list@mulberrytech.com]On Behalf Of John E. Simpson
Sent: Thursday, September 28, 2000 11:34 AM
To: 'xsl-list@mulberrytech.com'
Subject: Matching nodes in the default namespace
Have tried this with both Saxon and IE5.5+; neither seems to work as
expected. Also checked Mike Kay's book but haven't found anything yet.
Here's the XML:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="test.xsl"?>
<!--catalog last updated 2000-11-01-->
<catalog xmlns="http://www.example.com/catalog/">
<book id="bk101">
<author>Some author</author>
<title>Some Title</title>
<genre>Some genre</genre>
<price>Some price</price>
<publish_date>Some date</publish_date>
<description>Some description</description>
</book>
</catalog>
And here's test.xsl:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/TR/REC-html40" >
<xsl:template match="/">
<html>
<title>Book catalog</title>
<body>
<table border="1">
<tr>
<th>Author</th>
<th>Title</th>
<th>Genre</th>
<th>Price</th>
<th>Pub Date</th>
<th>Description</th>
</tr>
<xsl:apply-templates select="*"/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="catalog">
<xsl:apply-templates/>
</xsl:template>
<!-- Suppress individual children of <book>, and built-in
processing of all text nodes -->
<xsl:template
match="author|title|genre|price|publish_date|description|text()"/>
<xsl:template match="book">
<tr>
<td><xsl:value-of select="author"/></td>
<td><cite><xsl:value-of select="title"/></cite></td>
<td><xsl:value-of select="genre"/></td>
<td><xsl:value-of select="price"/></td>
<td><xsl:value-of select="publish_date"/></td>
<td><xsl:value-of select="description"/></td>
</tr>
</xsl:template>
</xsl:stylesheet>
What happens is that the match/select expressions locate *nothing* in the
XML doc (so I get a result tree consisting of the table headers, but
otherwise nothing else). If I take out the default namespace declaration in
the <catalog> element, it works exactly as expected. Clearly, the
match/select are attempting to match on the fully expanded node names (i.e.
including namespace URI) in the source tree.
What's the magic word that enables you to do a match/select on an element
in an explicitly URI'd default namespace?
P.S. Yes, I know there's no reason to use any namespace decl. at all in the
doc, since its contents don't come from more than one namespace. The
question remains, though -- how do you match on a null namespace prefix
that's nonetheless associated with a namespace URI?
==========================================================
John E. Simpson | "If you were going to
http://www.flixml.org | shoot a mime, would you use
XML Q&A: http://www.xml.com | a silencer?" (Steven Wright)
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list