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

Subject: Re: [xsl] translate to XML using XSL into an HTML table
From: Steve <subsume@xxxxxxxxx>
Date: Fri, 3 Aug 2007 18:11:45 -0400
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.online@xxxxxxxxx> 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/

Current Thread