This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

RE: Matching nodes in the default namespace



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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]