XQuery/Displaying data in HTML Tables

From Wikibooks, open books for an open world
Jump to: navigation, search

Motivation[edit]

You would like to display your XML data in an HTML table and display alternate rows using a colored background.

Data File[edit]

Assume you have a data file such as the following XML file which is a sample glossary of terms and definitions:

terms.xml[edit]

<terms>
   <term>
      <term-name>Object</term-name>
      <definition>A set of ideas,
 
      </definition>
   </term>
   <term>
      <term-name>Organization</term-name>
      <definition>A unit consisting of people and processes established
      to perform some functions</definition>
   </term>
   <term>
      <term-name>Organization</term-name>
      <definition>BankOfAmerica</definition>
   </term>
</terms>

The <term> tags will repeat for each term in your glossary.

You would like to display these terms in an HTML table.

Screen Image[edit]

HTML table screen image

The following XQuery will perform the task.

Sample Code[edit]

xquery version "1.0";
declare option exist:serialize "method=xhtml media-type=text/html";
 
let $my-doc := doc('https://idesk.invismi.ca/actions/getRates.cfm?wid=11001552')
return
<html>
    <head>
        <title>Current Rates</title>
    </head>
    <body>
    <table border="1">
    <thead>
      <tr>
          <th>term</th> 
          <th>postedrate</th>
          <th>ourrate</th>
      </tr>
    </thead>
    <tbody>{
         for $rate in $my-doc/body/rate
         return            
         <tr>       
           <td>{$rate/term/text()}</td>
           <td>{$rate/postedrate/text()}</td>
           <td>{$rate/ourrate/text()}</td>
         </tr>
       }</tbody>
     </table>
   </body>
</html>

Execute

Discussion[edit]

Sorting before counting[edit]

There are two nested for loops. The outer loop has the additional at count parameter that increments a counter for each result returned. The inner loop has the loop that returns a generic sorted item to the outer loop. Note that the inner loop does the sorting first and the outer loop does the counting of each item so that alternate rows are shaded.

Note that if you know the original file is in the correct order the nested for loops are not necessary. A single for loop with the at $count is all that is needed.

Dynamic Element Construction[edit]

The following lines:

<tr> {if ($count mod 2)
         then (attribute bgcolor {'Lavender'})
         else ()}

conditionally creates a light blue background color for odds rows, rows which evaluate true because modulus 2 of their $count is not zero. This is an example of dynamic element construction.

Odd rows:

<tr bgcolor="Lavender">
   <td>...</td>
</tr>

Even rows:

<tr><td>...</td></tr>

It does this by conditionally adding an attribute bgcolor="Lavender" for odd rows in the table. If the test ($count mod 2) is zero, i.e. on even rows, an attribute will not be added.

It is recommended best practice that the style of shading alternate rows of a table be done in a central cascading style sheet. The most general way to keep the table formats standard throughout your site would be to add semantic class tags to each row to label them even or odd.

<tr> {if ($count mod 2)
         then (attribute  class  {'even'})
         else (attribute  class  {'odd'})}

The CSS file would then contain the following:

.odd {background-color: Lavender;}