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

RE: Problems with XSL, XML code

Subject: RE: Problems with XSL, XML code
From: "Evan Lenz" <elenz@xxxxxxxxxxx>
Date: Tue, 3 Oct 2000 10:36:30 -0700
xsl pattern all children of
Good explanation, John.  Maybe I could make just two corrections:

1. Why the default namespace?  That's not necessary; literal result elements
don't have to be in a namespace.

2. If you remove HORA from the template rule's match pattern, the <HORA>
child will still be processed by <xsl:apply-templates/>, which processes
each child (elements, text, processing instructions, and comments) of the
current node.  In this case, the children consist only of elements (and
whitespace text nodes which don't cause any important difference as will
become clear).  If a template rule is not found that matches a given child,
then the built-in template rule for that node type is used.  In the case of
an element, the built-in rule is to simply apply templates to its children.
<HORA>'s child consists of a text node.  Since there are no explicit
template rules matching text nodes, the built-in rule for text nodes will be
applied, which is to copy the text to the result tree.  Thus, you would end
up copying "10:08", etc. to the result tree.  There are two ways to solve
this problem as follows:

  I. Catch text nodes with a template rule that does nothing:  <xsl:template
match="text()"/>

  II. Selectively process the children:  <xsl:apply-templates
select="*[local-name()!='HORA']"/>

In the second case, your template rule need only match "*" which will match
any element.

Hope this helps,

Evan Lenz
elenz@xxxxxxxxxxx
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@xxxxxxxxxxxxxxxx
[mailto:owner-xsl-list@xxxxxxxxxxxxxxxx]On Behalf Of John E. Simpson
Sent: Tuesday, October 03, 2000 8:15 AM
To: xsl-list@xxxxxxxxxxxxxxxx
Subject: Re: Problems with XSL, XML code


At 05:24 AM 10/03/2000 -0700, Marcos Coelho wrote:
>I felt I was not very clear, so I made an Webpage where I explainedmy
>problem better I wish.
>There I put my XML, XSL, and the OUT PUTS files which I want and what I
>got!
>The address is
>http://www.geocities.com/marcos_coelho/xml/doubt.htm

Marcos, I looked at your page. Actually, I'm surprised you got *any*
output, as your stylesheet is not legitimate. (What XSLT processor are you
using?)

First, you don't need the xmlns:fo namespace declaration, since you're not
using any elements whose names begin with "fo:".

Second, you *do* need a default namespace declaration for the HTML
namespace, since all the result-tree (HTML) elements in the stylesheet have
no prefixes. So just replace the xmlns:fo declaration with:

   xmlns="http://www.w3.org/TR/REC-html40"

Third, you've got an <xsl:value-of> element which contains an
<xsl:template> element. Saxon reports (rightly) that <xsl:value-of> must be
an empty element. Remove the <xsl:value-of...> and </xsl:value-of> start
and end tags. (Leave what it contains for now.)

Saxon now reports (rightly) that <xsl:template> is a top-level element.
That means it must be a child of the root <xsl:stylesheet> element. So move
the start and end tags of the xsl:template element so they contain
everything else. That is, you should at this point have:

<xsl:stylesheet [...namespace decls....]>
<xsl:template match="COSMO">
   <html>
     <head>
       <title>XML --> XSL ---> HTML </title>
     </head>
   <body>
     <table>
       <tr>
         <xsl:for-each select="NOTICIAS">
           <td><!-- 1 col --><xsl:for-each select="TITULO"/></td>
           <td><!-- 2 col --><xsl:for-each select="DATA"/></td>
           <td><!-- 3 col --><xsl:for-each select="HORA"/></td>
           <td><!-- 4 col --><xsl:for-each select="CONTEUDO"/></td>
           <td><!-- 5 col --><xsl:for-each select="AUTOR"/></td>
           <td><!-- 6 col --><xsl:for-each select="CODIGO"/></td>
           <td><!-- 7 col --><xsl:for-each select="TIPO"/></td>
         </xsl:for-each>
       </tr>
     </table>
   </body>
   </html>
</xsl:template>
</xsl:stylesheet>

(Btw, to run this in Saxon or IE5.5+, you'll probably also need to add an
encoding declaration to your XML document, that is:
    <?xml version="1.0" encoding="iso-8859-1" ?>
That's because of the extended ASCII characters such as ã that are in your
document.)

When you run this, you indeed get an empty table displayed. Why is that?
For an answer, look at any one of your <td> elements in the stylesheet,
e.g.:

      <td><!-- 1 col --><xsl:for-each select="TITULO"/></td>

What you're inserting in there within the <td> element is... precisely
nothing! The <xsl:for-each> element doesn't place anything at all in the
result tree.

So let's try replacing each of those <xsl:for-each> elements with an
<xsl:value-of>, e.g.:

      <td><!-- 1 col --><xsl:value-of select="TITULO"/></td>

Let's also add a border to the table which (I can safely report) will now
be displayed, to help in debugging the output.

As you can see if you've done the above, now you've got output, but the
order/display is goofed up -- it's all in one long row! And why is that?
Because that's what your template for the <COSMO> template says to do.
There's only one <tr> element created in the result tree for a given
<COSMO> element. But according to your explanation at the page you cited
above, you want one row for each *child* of each <NOTICIAS> element.

So let's change the one template rule to two. The first will handle your
<COSMO> element more or less as is; the second will handle all children of
the <NOTICIAS> element. The most important change is to break out the <tr>
and <td> elements to be created in the result tree so that they're in this
second template rule.

<xsl:template match="COSMO">
   <html>
     <head>
       <title>XML --> XSL ---> HTML </title>
     </head>
   <body>
     <table border="1">
       <xsl:for-each select="NOTICIAS">
         <!-- Line below invokes template rule for all children
         of the <NOTICIAS> elements. -->
         <xsl:apply-templates/>
       </xsl:for-each>
     </table>
   </body>
   </html>
</xsl:template>

<xsl:template match="TITULO|DATA|TIPO|AUTOR|CODIGO|HORA|CONTEUDO">
   <tr>
     <td><xsl:value-of select="."/></td>
   </tr>
</xsl:template>

Output from this is not exactly as you'd requested. For example, you didn't
want to display the <HORA> element; if that's the case, simply remove it
(and the "|" of course!) from the second template rule's match pattern.

Does that help -- not just to solve your problem(s), but to understand what
you need to do from here?

==========================================================
John E. Simpson               | "Curiosity killed the cat,
http://www.flixml.org         | but for a while I was a
XML Q&A: http://www.xml.com   | suspect." (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


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.