xsl-list
[Top] [All Lists]

Re: [xsl] translate to XML using XSL into an HTML table

2007-08-03 15:12:12
Not to be ignored!

(even though I, being relatively new myself, know its overwhelming.
you will see the light!)

On 8/3/07, Abel Braaksma <abel(_dot_)online(_at_)xs4all(_dot_)nl> wrote:
Oryann,

You have already been helped very well with the code below, but the
discussion stayed all around using the same construct: xsl:for-each. You
stated that you are new to XSLT, so I take it that you are not very
familiar with it. In a later post you say that you are accustomed to
Perl, which is, as many general domain and scripting languages, an
imperative language, where you are used to be in charge yourself of
telling the compiler what to do and when, and XSLT takes it just the
other way around.

Your approach below does exactly that: you layout a table, and you use
for-each to tell the compiler (xslt processor) to get a group of
elements and to do something with it. This is not wrong on itself, but
if your code will grow, you will find yourself having very complex and
hard to maintain structures, just like a nested for/next and if/then
would give you in an imperative language (unless you choose to use its
OO capabilities etc to get your code more readable).

XSLT is a declarative / functional language. You literally *declare*
what your output should look like based on a set of rules, and then you
let the processor do the brainy stuff for you. What you need to know is
that the processor will walk the input tree of XML for you and you
declare templates where you say "if the processor encounters node XYZ
create a TD tag" and "if the processor encounters node ABC create a
TABLE tag". To control this flow, you can select what nodes the
processor is allowed to process on a given position.

To illustrate this approach, let's take your example. Instead of writing
a for-each loop (it is not hard to imagine how your code will look when
you need several tables inside one another, with several for-each loops
etc), you can take the following approach, which needs a little shift in
thinking (read along with the comment lines):

<xsl:template match="/">
    <!-- here comes your frameword for the html page -->
    <html>
        <head>.....</head>
        .... etc ....
        <body>
             <!-- now we tell the processor what main elements to grab -->
             <!-- these are children of the root -->
             <xsl:apply-templates select="PHONEBOOK" />
        </body>
     </body>
</xsl:template>

<!-- declaring the table, which starts for each PHONEBOOK (only one) -->
<xsl:template match="PHONEBOOK">
      <!-- here comes the start of the table, you could put it in the
main, but this keeps it cleaner -->
      <table border="3">
           <!-- table header -->
           <tr bgcolor="lightblue">
               <th>FirstName</th>
               <th>LastName</th>
               <th>Phone</th>
           </tr>
          <!-- here we say to the processor: take these elements that we
want a rows -->
          <!-- I assume that you have added a <member> around each
first/last/phone, though this is not necessary -->
          <xsl:apply-template select="MEMBER" />
      </table>
</xsl:template>

<!-- declaring the row, which the processor will automatically select
for each MEMBER -->
<xsl:template match="MEMBER">
     <!-- here goes the row definition
            all is a client of MEMBER now -->
     <!-- an easy way to create a way so you can point your browser
             to each member by its id or name (IE), by using
http://yoururl/yourpath#memberID -->
     <xsl:variable name="id"><xsl:number /></xsl:variable>
     <tr id="member-{$id}">
            <xsl:apply-templates select="FIRST | LAST | PHONE" />
     </tr>
</xsl:template>

<!-- declare the cells, which is any node that is a child of MEMBER -->
<xsl:template match="MEMBER/*">
     <!-- here we select the value of the current node (.) -->
     <td><xsl:value-of select="." /></td>
</xsl:template>


Now, the above is finished. If you use that, you will get a neatly
rendered table. Why is this better than the previous approach? Suppose
that you want to but the text of the first name (FIRST) into bold.

If you take your original approach, you would have to add a <xsl:if>
statement, which would even more deeply indent the already deeply nested
structure. In the new approach (the XSLT'ish approach) all you need to
is make a specific exception for the FIRST nodes, which you do by adding
an extra declaration, that is all. The processor "knows" that it should
take the exception case, instead of the generic case and will
automatically choose the correct declaration.

This is what I meant by: let the processor do the thinking for you. This
is also the one point that many people find rather daunting when
attacking XSLT at first, but once understood it will make you go like
lightspeed!

Here's what you do, just add this to the code above, and you are done:

<xsl:template match="FIRST">
     <td><b><xsl:value-of select="."></b><td>
</xsl:template>


These concepts are very well presented in Jeni Tennison's tutorial
books. You can also check her website. Another good starting point is
the XSLT Cookbook (consider the second edition only) and Dave Pawson's
FAQ (search google for XSLT FAQ followed by your query and you get
there). If you want to get a bit further on the subject, you should
consider buying the authoritative definitive books on XPath 2.0 and XSLT
2.0 by Michael Kay.

Hope it helps! Happy coding!

Cheers,
-- Abel Braaksma



oryann9 wrote:
Hello all ,

This is my 1st post so be kind...
Anywho... here is my xsl code and I need to make a
table for every entry in my XML code, but cannot get
it to work. Please help!
Thank you,
oryan

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
<xsl:output method="html"/>
<xsl:template match="/">
<html>
    <head>
         <title> My Phone Book</title>
    </head>
     <h2> My Phone Book </h2>
    <body bgcolor="YELLOW">
        <table border="3">
           <tr bgcolor="lightblue">
               <th>FirstName</th>
               <th>LastName</th>
               <th>Phone</th>
           </tr>
            <xsl:for-each select="//FIRST">
            <tr>
                <td> <xsl:value-of
select="//FIRST/*"/>

                </td>
            </tr>
            </xsl:for-each>
        </table>
    </body>
</html>
</xsl:template>
</xsl:stylesheet>


XML CODE:

<?xml version="1.0"?>
<!DOCTYPE PHONEBOOK>
<PHONEBOOK>
    <LISTING>
        <FIRST> Derek </FIRST>
        <LAST> Smith </LAST>
        <PHONE> 614-757-2123 </PHONE>

        <FIRST> Steve </FIRST>
        <LAST> Gretschmann </LAST>
        <PHONE> 614-757-2323 </PHONE>

        <FIRST> Corey </FIRST>
        <LAST> Pohl </LAST>
        <PHONE> 614-806-1416 </PHONE>

        <FIRST> Tiko </FIRST>
        <LAST> Lewis </LAST>
        <PHONE> 614-232-3434 </PHONE>

        <FIRST> Kurt </FIRST>
        <LAST> Smith </LAST>
        <PHONE> 419-455-9090 </PHONE>
    </LISTING>

    <LISTING>
       <FIRST>Jane</FIRST>
       <LAST>Smith</LAST>
       <PHONE>1-800-234-5678</PHONE>
       <PHONE>1-555-222-3333</PHONE>
    </LISTING>

</PHONEBOOK>



____________________________________________________________________________________
Looking for a deal? Find great prices on flights and hotels with Yahoo! 
FareChase.
http://farechase.yahoo.com/

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--






--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--