XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition (173 page)

BOOK: XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition
8.72Mb size Format: txt, pdf, ePub

If you wanted to be clever you could handle the


,


,


, . . . ,

elements with a single generic rule. This could be done by writing the template rule as:


  

  

                select=“translate($this, ‘12345678’, ‘23456789’)”/>

  


    

                      group-starting-with=“*[name()=$next]”>

      

    

  



Using group-ending-with

The
group-ending-with
option complements
group-starting-with
by matching the last item in a group instead of the first. This requirement is far less common, but it does arise. The classical example for it is where a large document has been broken up, for transmission reasons, into small arbitrary chunks, and the last chunk carries some distinguishing characteristic such as the absence of an attribute saying
continued=“yes”
. To reconstitute the documents from the sequence of chunks,
group-ending-with
is the answer:



   

       

   



I have also found
group-ending-with
useful on occasions when writing an up-conversion to XML from formats such as Excel spreadsheets, where the last line of a group can be detected by the presence of a word such as
TOTAL
or
SUBTOTAL
in a particular column.

Arranging Data in Tables

Arranging data in tables is a common requirement when generating HTML pages, and the

instruction can help with this in a number of ways. I will not present any detailed worked examples here, just a checklist of techniques. However, the examples are expanded in the download files: see
towns.xml
,
towns-by-rows.xsl
, and
towns-by-columns.xsl
.

If you need to arrange data in rows, like this:

the simplest approach is this, where
$cols
is the number of columns required:

                     group-adjacent=“(position()-1) idiv $cols”>


   

   

      

   

   



If the data needs to be sorted first, use the

instruction. For example:


  

     

  


                     group-adjacent=“(position()-1) idiv $cols”>

   …


The

instruction is described on page 437.

If you need to generate empty table cells to fill up the last row, one convenient way is to add them to the sequence before you start:

     select=“(count(towns) idiv $cols)*$cols + $cols - count(towns)”/>

   if ($gaps = $cols) then () else for $i in 1 to $gaps return ‘ ’”/>



  …


If you want to arrange the data in columns, like this:

then it is probably simplest to use
group-by
. The grouping key (the things that the towns in a particular row have in common) is the value of
position() mod 3
where 3 is the number of rows, which you can calculate as
count($cells) idiv $cols
):

Other books

Flashback by Nevada Barr
Knot Guilty by Betty Hechtman
Colin's Quest by Shirleen Davies
MotherShip by Tony Chandler
Estudio en Escarlata by Arthur Conan Doyle
Photo Finish by Kris Norris