Perform Iterations
The sales data in Sales.xml consists of three regions: West Coast, Central, and East Coast. There are four quarters for each region.
... <data> <region> <name>West Coast</name> <quarter number="1" books_sold="24000" /> <quarter number="2" books_sold="38600" /> <quarter number="3" books_sold="44030" /> <quarter number="4" books_sold="21000" /> </region> <region> <name>Central</name> <quarter number="1" books_sold="11000" /> <quarter number="2" books_sold="16080" /> <quarter number="3" books_sold="25000" /> <quarter number="4" books_sold="29000" /> </region> <region> <name>East Coast</name> <quarter number="1" books_sold="27000" /> <quarter number="2" books_sold="31400" /> <quarter number="3" books_sold="40100" /> <quarter number="4" books_sold="30000" /> </region> </data> ...
There are two repeating elements in this file: <region>
, and within each <region>
, <quarter>
. This suggests an array-like or list-like data structure. As in other programming languages, such as C/C++, Visual Basic, and JScript, you can handle this kind of repeating data set in XSLT with a loop, or recursion. This exercise demonstrates how to process an array-like or list-like data set in loops with the help of the xsl:for-each
instruction.
To format the <data> section into table cells
- Use your HTML or text editor to open Transform.xsl and locate the
</body>
line. - Immediately above the
</body>
line, replace the two<DIV>...</DIV>
statements with the following code:<table> <!-- Create a table heading row, filling in the quarter numbers from left to right. --> <tr> <th>Region\Quarter</th> <xsl:for-each select="//data/region[1]/quarter"> <th>Q<xsl:value-of select="@number"/></th> </xsl:for-each> <th>Total</th> </tr> <!-- Create a table body row for each quarter of each region, filling cells with the number of books sold. --> <xsl:for-each select="//data/region"> <tr> <th style="text-align:left"><xsl:value-of select="name"/></th> <xsl:for-each select="quarter"> <td style="text-align:right"> <xsl:value-of select="format-number(@books_sold,'###,###')"/> </td> </xsl:for-each> <td style="text-align:right;font-weight:bold;"> <!-- Total will go here. --> </td> </tr> </xsl:for-each> </table>
- Save Transform.xsl. You can leave this file open.
To view the transformation of the <data> element
- In Internet Explorer, press F5 to refresh Sales.xml.
The new portion of the sales report should look like this:
- If you installed the Internet Explorer Tools for Validating XML and Viewing XSLT Output, you can also right-click in the Internet Explorer window and then click View XSL Output menu item.
How the Transform Works
This topic focuses on those parts of the transformation that are related to the xsl:for-each
statements.
The first part of these new statements, xsl:for-each
, tells the parser to do something every time it finds the pattern defined by the second part of the statement. For example, the statement <xsl:for-each select="//data/region[1]/quarter">
indicates that something should be done every time the parser finds the <quarter>
element within the first <region>
element.
The formatting statements that follow each xsl:for-each
statement define exactly what the parser has to do when it encounters the specified pattern. For example, the formatting statement that follows the <xsl:for-each select="//data/region[1]/quarter">
statement is <th>Q<xsl:value-of select="@number"/>
. This formatting statement indicates that the parser needs to look inside the <quarter>
element, get the value of the number
attribute, and insert that value into the table header after the letter "Q".
So far, we dealt with data display in an XSLT transformation. However, XSLT is not limited to display, or style. You can use XSLT to implement logic, as well as to enact programming flow-control. The next exercise shows how to Operate on Data Values—that is, how to perform arithmetic operations in XSLT.