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

Re: XSLT repetition constructs comparison

Subject: Re: XSLT repetition constructs comparison
From: "Michael Kay mike@xxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 14 Jan 2021 09:19:30 -0000
Re:  XSLT repetition constructs comparison
I would personally only use xsl:iterate where you need something that
xsl:for-each can't do, such as early exit, or accumulation of parameter
values. But an xsl:iterate with no parameters, no xsl:break, no
xsl:on-completion is equivalent to xsl:for-each so there's no intrinsic reason
to prefer one over the other. There may be implementation differences but
that's processor-specific.

If you need some of the features of xsl:iterate and also want sorting, then I
would normally use the sort() function:

<xsl:iterate select="sort(student, (), function($s){$s/(fName, lName))">...

or if that's not possible (e.g because you need a descending sort), then sort
first (into a variable) using xsl:perform-sort.

Michael Kay
Saxonica

> On 14 Jan 2021, at 09:05, Mukul Gandhi mukulg@xxxxxxxxxxxxxxxxx
<xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:
>
> Hi all,
>    I'm comparing the functionality of, XSLT repetition constructs
xsl:for-each and xsl:iterate (versions 2.0 & 3.0). Below is my example use
case, and the corresponding XSLT solutions from my side,
>
> XML input document:
>
> <?xml version="1.0"?>
> <students>
>    <student>
>       <rollNo>1</rollNo>
>       <fName>Sharon</fName>
>       <lName>Adler</lName>
>    </student>
>    <student>
>       <rollNo>2</rollNo>
>       <fName>Anders</fName>
>       <lName>Berglund</lName>
>    </student>
>    <student>
>       <rollNo>3</rollNo>
>       <fName>Norm</fName>
>       <lName>Walsh</lName>
>    </student>
>    <student>
>       <rollNo>4</rollNo>
>       <fName>Michael</fName>
>       <lName>Sperberg-McQueen</lName>
>    </student>
>    <student>
>       <rollNo>5</rollNo>
>       <fName>Florent</fName>
>       <lName>Georges</lName>
>    </student>
> </students>
>
> I wish to transform, the above XML data into HTML, using XSLT. The resulting
HTML, needs to have a table containing rows representing each XML input
"student" element, and a total record count at the bottom of HTML output.
>
> Below are my various XSLT solutions,
>
> (1) An XSLT 2.0 solution, with sorting (sorting by fName & lName):
>
> <?xml version="1.0"?>
> <xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform
<http://www.w3.org/1999/XSL/Transform>">
>
>    <xsl:output method="html" indent="yes"/>
>
>    <xsl:template match="students">
>       <html>
>         <head>
>            <title>Student list</title>
>         </head>
>         <body>
>            <table>
>               <tr>
>                  <td><b>Roll No.</b></td>
>                  <td><b>First name</b></td>
>                  <td><b>Last name</b></td>
>               </tr>
>               <xsl:for-each select="student">
>                  <xsl:sort select="fName"/>
>                  <xsl:sort select="lName"/>
>                  <tr>
>                     <td align="center"><xsl:value-of
select="rollNo"/>.</td>
>                     <td><xsl:value-of select="fName"/></td>
>                     <td><xsl:value-of select="lName"/></td>
>                  </tr>
>               </xsl:for-each>
>               <tr>
> 	        <td colspan="3">&#xa0;</td>
> 	      </tr>
> 	      <tr>
> 	        <td colspan="2"><b>Total no of students</b> : </td>
> 	        <td><xsl:value-of select="count(student)"/></td>
>               </tr>
>            </table>
>         </body>
>       </html>
>    </xsl:template>
>
> </xsl:stylesheet>
>
> (2) An XSLT 3.0 solution, without sorting:
>
> <?xml version="1.0"?>
> <xsl:stylesheet version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform
<http://www.w3.org/1999/XSL/Transform>"
>
xmlns:xs="http://www.w3.org/2001/XMLSchema
<http://www.w3.org/2001/XMLSchema>"
>
exclude-result-prefixes="xs">
>
>    <xsl:output method="html" indent="yes"/>
>
>    <xsl:template match="students">
>       <html>
>         <head>
>            <title>Student list</title>
>         </head>
>         <body>
>            <table>
>               <tr>
>                  <td><b>Roll No.</b></td>
>                  <td><b>First name</b></td>
>                  <td><b>Last name</b></td>
>               </tr>
>               <xsl:iterate select="student">
>                  <xsl:param name="total" select="0" as="xs:integer"/>
>                  <xsl:on-completion>
>                     <tr>
>                        <td colspan="3">&#xa0;</td>
>                     </tr>
>                     <tr>
>                       <td colspan="2"><b>Total no of students</b> : </td>
>                       <td><xsl:value-of select="$total"/></td>
>                     </tr>
>                  </xsl:on-completion>
>                  <tr>
>                     <td align="center"><xsl:value-of
select="rollNo"/>.</td>
>                     <td><xsl:value-of select="fName"/></td>
>                     <td><xsl:value-of select="lName"/></td>
>                  </tr>
>                  <xsl:next-iteration>
>                     <xsl:with-param name="total" select="$total + 1"/>
>                  </xsl:next-iteration>
>               </xsl:iterate>
>            </table>
>         </body>
>       </html>
>    </xsl:template>
>
> </xsl:stylesheet>
>
> (3) An XSLT 3.0 solution, with sorting:
>
> <?xml version="1.0"?>
> <xsl:stylesheet version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform
<http://www.w3.org/1999/XSL/Transform>"
>
xmlns:xs="http://www.w3.org/2001/XMLSchema
<http://www.w3.org/2001/XMLSchema>"
>
exclude-result-prefixes="xs">
>
>    <xsl:output method="html" indent="yes"/>
>
>    <xsl:template match="students">
>       <html>
>         <head>
>            <title>Student list</title>
>         </head>
>         <body>
>            <table>
>               <tr>
>                  <td><b>Roll No.</b></td>
>                  <td><b>First name</b></td>
>                  <td><b>Last name</b></td>
>               </tr>
>               <xsl:variable name="result_1" as="element(tr)*">
>                  <xsl:iterate select="student">
>                     <xsl:param name="total" select="0" as="xs:integer"/>
>                     <xsl:on-completion>
>                        <tr>
>                           <td colspan="3">&#xa0;</td>
>                        </tr>
>                        <tr>
>                          <td colspan="2"><b>Total no of students</b> :
</td>
>                          <td><xsl:value-of select="$total"/></td>
>                        </tr>
>                     </xsl:on-completion>
>                     <tr>
>                        <td align="center"><xsl:value-of
select="rollNo"/>.</td>
>                        <td><xsl:value-of select="fName"/></td>
>                        <td><xsl:value-of select="lName"/></td>
>                     </tr>
>                     <xsl:next-iteration>
>                        <xsl:with-param name="total" select="$total + 1"/>
>                     </xsl:next-iteration>
>                  </xsl:iterate>
>               </xsl:variable>
>               <xsl:perform-sort select="$result_1[position() le
(count($result_1)-2)]">
>                  <xsl:sort select="td[2]"/>
>                  <xsl:sort select="td[3]"/>
>               </xsl:perform-sort>
>               <xsl:copy-of select="$result_1[position() gt
(count($result_1)-2)]"/>
>            </table>
>         </body>
>       </html>
>    </xsl:template>
>
> </xsl:stylesheet>
>
> I haven't mentioned the solution, where we could use xsl:apply-templates
instead of xsl:for-each or xsl:iterate.
>
> Firstly, I find xsl:iterate much more functionally rich (except that it
doesn't provide native sorting support) than xsl:for-each, if there's a
requirement of XSLT sequential looping. If there's no requirement for sorting,
then in XSLT 3.0 environment, I'd opt to use xsl:iterate. If there's
requirement for sorting, then in XSLT 3.0 environment, I might opt to use
xsl:for-each instead of xsl:iterate (does anybody differ?). When using XSLT
3.0 xsl:iterate, with a requirement of sorting, can anyone suggest a different
(and possibly better as well) solution than (3) above?
>
> Any thoughts, about performance aspects of various XSLT solutions relevant
to this thread, would also be useful to know.
>
>
>
> --
> Regards,
> Mukul Gandhi
> XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>
> EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/293509> (by
email <>)

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.