Re: [xsl] How to calculate column number of the entry?

Subject: Re: [xsl] How to calculate column number of the entry?
From: Wendell Piez <wapiez@xxxxxxxxxxxxxxxx>
Date: Thu, 28 May 2009 12:30:34 -0400

At 11:13 PM 5/27/2009, you wrote:
Toshihiko Makita wrote:
> I am developing DocBook table to XSL-FO stylesheet. It is not
> specialized for specific user use. It should be a general stylesheet.

Wow... you are taking on by far the most complicated kind of markup in

Yup: OASIS (CALS) tables.

I would very, very strongly recommend using the DocBook XSL stylesheets
as a starting point.  Even if you donbt use any of their
transformations, there is a large library of utility functions contained
in them for doing things like figuring out table cell column numbers,
alignment, etc.

On the other hand, TMK these have not been done in XSLT 2.0, and the XSLT 1.0 Docbook table code is necessarily something of a tour-de-force. XSLT 1.0 was just not designed to make this sort of thing easy.

A set of XSLT 2.0 OASIS/CALS/Docbook table
modules would be a fine thing, if the community could share.

As for the question, the trick is in defining the
specification. The table model is complex to
implement, and most implementations (in my
experience) don't do the entire thing.
Makita-san's description appears to be fairly complete:

1. The table columns are described with colspec element like follows:

   <colspec colname="col1" colwidth="1*"/>
   <colspec colname="col2" colwidth="2*" align="right"/>
   <colspec colname="col3" colwidth="2*"/>

2. Usually XSL-FO property is inherited from fo:table-and-caption ==>
fo:table ==> fo:table-header, fo:table-footer, fo:table-body ==>
fo:table-row ==> fo:table-cell. However I want to apply colspec/@align
attribute using from-table-column() function to fo:table-cell *only*
when it is defined in colspec element. In the above example, I want to
apply text-align="right" to the fo:table-cell only when its column
number is 2.

   <fo:table-cell text-align="from-table-column()">

3. To know colspec/@align is defined or not in colspec, it is necessary
to know what column number current entry is. The entry element defines
colname, namest or spanname attribute. If one of them is specified, the
stylesheet can calculate column number from the attribute value. But
these attributes are not mandatory.

4. If above attributes are not defined in the entry element, the
stylesheet must calculate the column number by itself. I think it is
easy when the table has no row spans. If there are row spans, it may be
impossible for stylesheet to calculate the correct column number.

Using XSLT 2.0, I would take the approach of a function that would return the column number, or perhaps even better the proper 'colspec' element itself, falling back from one to the next of the means described.

I don't think even 4 is impossible, if a column
number can be defined as 1 + the sum of all the
column spans on preceding sibling cells, falling
back to 1 when colspan is not defined:

n = 1 + sum(preceding-sibling::entry/t:colspan(.) )

where the function t:colspan() returns the column
span for the cell. This is defined on the cell,
or if not by means of colspecs when available, or as 1 by default.

Indeed, this is effectively what the 1.0 Docbook
stylesheets do, except that named templates
returning result-tree-fragments have to be used instead of actual functions.

Another nice thing offered by this function
library would be a set of assertions (XSLT or
Schematron) that could check whether a table were
"square" (rows all the same length).


Wendell Piez                            mailto:wapiez@xxxxxxxxxxxxxxxx
Mulberry Technologies, Inc.      
17 West Jefferson Street                    Direct Phone: 301/315-9635
Suite 207                                          Phone: 301/315-9631
Rockville, MD  20850                                 Fax: 301/315-8285
  Mulberry Technologies: A Consultancy Specializing in SGML and XML

Current Thread