xsl-list
[Top] [All Lists]

RE: [xsl] Transforming Tables - repost

2006-05-16 01:20:14
It might be just me, but I'm finding that the lexical issues of non-XML
markup get in the way of understanding the structural transformation issues.
I would be inclined to split the problem into two: first get the structure
right with a regular XML-to-XML transformation, then do a second phase to
produce the proprietary markup syntax. 

I think I would tackle the rowspans with a multi-pass approach: do a
pre-pass of the data in which any cell with a rowspan is copied into the
subsequent rows, with some kind of attribute to mark it as such. The logic
would be something like:


<xsl:template match="row" mode="expand-rowspan">
  <xsl:variable name="new-cells">
    <xsl:copy-of select="cell">
    <xsl:for-each select="preceding-sibling::row/cell[f:row-number(..) +
@rowspan -1 gt f:row-number(current()) ]">
       <xsl:copy>
         <xsl:copy select="@col"/>
         <xsl:attribute name="copied" select="true()"/>

where f:row-number computes the number of a row.

Michael Kay
http://www.saxonica.com/

-----Original Message-----
From: Jeff Sese [mailto:jsese(_at_)asiatype(_dot_)com] 
Sent: 16 May 2006 07:58
To: Xsl-List
Subject: [xsl] Transforming Tables - repost

Good day!

I'm transforming a table xml into a InDesign tagged text 
table using XSLT 2.0 on Saxon and i'm having a problem when 
it comes to spanning. In InDesign tagged text a cell is 
constructed this way: 
<clStart:x,y>data<clEnd:>, x is the number of rows and y the 
number columns occupied by the cell. However, if the table 
has 5 columns then each row must have 5 cell entries as well 
regardless if there exist a cell the spans the rest of the 
column or a previous cell that spans the row position.

So if you have a table xml like this:
<table row="4" col="5">
<row>
<cell col="1">Data</cell>
<cell col="2" colspan="3">Data</cell>
<cell col="5">Data</cell>
</row>
<row>
<cell col="1" rowspan="3">Data</cell>
<cell col="2">Data</cell>
<cell col="3">Data</cell>
<cell col="4">Data</cell>
<cell col="5">Data</cell>
</row>
<row>
<cell col="2" rowspan="2">Data</cell>
<cell col="3">Data</cell>
<cell col="4">Data</cell>
<cell col="5">Data</cell>
</row>
<row>
<cell col="3">Data</cell>
<cell col="4">Data</cell>
<cell col="5">Data</cell>
</row>
</table>

I should have a InDesign tagged text like this:
<tStart:4,12>
<rStart:>
<cStart:1,1>Data<cEnd:>
<cStart:1,3>Data<cEnd:>
<cStart:1,1><cEnd:>
<cStart:1,1><cEnd:>
<cStart:1,1>Data<cEnd:>
<rEnd:>
<rStart:>
<cStart:3,1>Data<cEnd:>
<cStart:1,1>Data<cEnd:>
<cStart:1,1>Data<cEnd:>
<cStart:1,1>Data<cEnd:>
<cStart:1,1>Data<cEnd:>
<rEnd:>
<rStart:>
<cStart:1,1><cEnd:>
<cStart:2,1>Data<cEnd:>
<cStart:1,1>Data<cEnd:>
<cStart:1,1>Data<cEnd:>
<cStart:1,1>Data<cEnd:>
</row>
<rEnd:>
<cStart:1,1><cEnd:>
<cStart:1,1><cEnd:>
<cStart:1,1>Data<cEnd:>
<cStart:1,1>Data<cEnd:>
<cStart:1,1>Data<cEnd:>
<rEnd:>
<tEnd:>

I can get my xslt to handle column spanning, but i'm having 
trouble with rowspanning. Here is my template for the cell element:

<xsl:template match="cell">
<xsl:variable name="col" select="if (exists(@colspan) then 
@colspan else 1)"/> <xsl:variable name="row" select="if 
(exists(@rowspan) then @rowspan else 1)"/> <xsl:value-of 
select="concat('<cStart:',$row,',',$col,'>')"/>
<xsl:apply-templates/>
<xsl:value-of select="'<cEnd:'"/>
<xsl:if test="exists(@colspan)">
<xsl:value-of select="for $x in (1 to @colspan-1) return 
'<cStart:1,1><cEnd:>'"/> </xsl:if> </xsl:template>

The template above generates empty cell markers based on the 
value of $col along the same row, because it is for the 
colspan. My problem is generating the empty cell markers for 
the rowspan. For example:

<row>
<cell col="1" rowspan="3">Data</cell>
<cell col="2">Data</cell>
<cell col="3">Data</cell>
<cell col="4">Data</cell>
<cell col="5">Data</cell>
</row>
<row>
<cell col="2" rowspan="2">Data</cell>
<cell col="3">Data</cell>
<cell col="4">Data</cell>
<cell col="5">Data</cell>
</row>
<row>
<cell col="3">Data</cell>
<cell col="4">Data</cell>
<cell col="5">Data</cell>
</row>

If i'm processing the 1st cell in the 2nd row, i must first 
insert an empty cell marker before it because the cell above 
it spans to 3 rows. 
Same goes for the 1st cell in the 3rd row only i must still 
add another empty marker before it because of the rowspan on 
the 1st cell in row 2. 
I having trouble referencing the preceding cellm element that 
span the particular row so that i can generate the 
corresponding empty cell markers. I tried using 
preceding::cell[1] but with i can't reference the
  other rowspan.

Can someone help me with generating the empty cells for row spanning?

Thanks,
Jeff




--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--