xsl-list
[Top] [All Lists]

Difficulty with semi-recursive operation in XSLT

2003-12-24 13:20:15
Happy Holidays, Everyone.

Here is my XML:

<?xml version="1.0" encoding="UTF-8"?>
<worksheet version="12.0.0.1" xmlns="urn:schemas-mathsoft-com:mcws"
xmlns:ml="urn:schemas-mathsoft-com:mcml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
xsi:schemaLocation="urn:schemas-mathsoft-com:mcws ../Worksheet.xsd">
        <settings>
                <presentation>
                        <pageModel>
                         <margins left="1.0" right="0.5" top="1.0"
bottom="0.5"/>
                         <header use-full-page-width="false"></header>
                         <footer use-full-page-width="false"></footer>
                        </pageModel>
                </presentation>
                <editor>
                        <ruler ruler-unit="in" is-visible="false">
                         <tabs>                 
                          <tab position="0.5" show-guide="false"/>
                          <tab position="1.0" show-guide="false"/>
                         </tabs>
                        </ruler>
                </editor>
        </settings>
        <regions>
         <region id="1">
          <text>
           <p style="Normal" tabs="0.2 1.2 2.2">
                Once upon a time, there was a <b>dark</b> and
<i>stormy</i> sea.              Nobody could be<br/>certain what lay
beneath it's churning                   surface.<br/>
                <tab/>One<tab/>Green<tab/>Octopus<br/>
                <tab/>Two<tab/>Red<tab/>Sharks<br/>
                Or something far more sinister?
           </p>                 
          </text>
         </region>
        </regions>
</worksheet>

And here is the XSL-FO output I'm trying to get:

<?xml version="1.0" encoding="utf-8"?>
<root xmlns="http://www.w3.org/1999/XSL/Format";
       font-family="Times" font-size="20pt">

   <layout-master-set>
     <simple-page-master master-name="frame"
                         page-height="11in" page-width="8.5in"
                         margin-top="1in" margin-bottom="1in"
                         margin-left="0.5in" margin-right="0.5in">

     <!-- NOTE: the useable page-width is 7.5in, the usable page-height
is      9in -->

       <region-body region-name="frame-body"/>
     </simple-page-master>
   </layout-master-set>

   <page-sequence master-reference="frame">
     <flow flow-name="frame-body">
       <block>
         Once upon a time, there was a <inline
font-weight="bold">dark</inline> and <inline font-style="italic">stormy
</inline> sea.  Nobody could be <block/>certain what lay beneath it's
churning surface.<block/>
       <table>
         <table-column column-width="0.2in"/>
         <table-column column-width="1.0in"/>
         <table-column column-width="1.0in"/>
         <!-- useable width of the last column, after there are no more
tabs: total usable page width minus total width of columns = (7.5in -
2.2in) = 5.3in-->
         <table-column column-width="5.3in"/>
         <table-body>
           <table-row>
             <table-cell><block/></table-cell>
             <table-cell><block>One</block></table-cell>
             <table-cell><block>Green</block></table-cell>
             <table-cell><block>Octopus</block></table-cell>
           </table-row>
           <table-row>
             <table-cell><block/></table-cell>
             <table-cell><block>Two</block></table-cell>
             <table-cell><block>Red</block></table-cell>
             <table-cell><block>Sharks</block></table-cell>
           </table-row>
         </table-body>
       </table>
       Or something far more sinister?
        </block>
     </flow>
   </page-sequence>
</root>

Here's what I have so far for a stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
xmlns:fo="http://www.w3.org/1999/XSL/Format";
xmlns:ws="urn:schemas-mathsoft-com:mcws"
xmlns:ml="urn:schemas-mathsoft-com:mcml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";>
        <xsl:output method="xml" indent="yes"/>
        <xsl:template match="ws:worksheet">
                <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format";>
                        <fo:layout-master-set>
                                <fo:simple-page-master
master-name="worksheet">
                                        <xsl:element
name="fo:region-body">
                                                <xsl:attribute
name="region-name"><xsl:text>xsl-region-body</xsl:text></xsl:attribute>
                                                <xsl:attribute
name="margin-top"><xsl:value-of
select="settings/presentation/pageModel/margins/@top"/></xsl:attribute>
                                                <xsl:attribute
name="margin-bottom"><xsl:value-of
select="settings/presentation/pageModel/margins/@bottom"/></xsl:attribut
e>
                                                <xsl:attribute
name="margin-left"><xsl:value-of
select="settings/presentation/pageModel/margins/@left"/></xsl:attribute>
                                                <xsl:attribute
name="margin-right"><xsl:value-of
select="settings/presentation/pageModel/margins/@right"/></xsl:attribute

                                        </xsl:element>
                                        <fo:region-before
precedence="true" border="none" region-name="xsl-region-before"
extent="0.5in" display-align="before"/>
                                        <fo:region-after
precedence="true" border="none" region-name="xsl-region-after"
extent="0.5in" display-align="after"/>
                                </fo:simple-page-master>
                        </fo:layout-master-set>
                        <fo:page-sequence master-reference="worksheet">
                                <fo:flow flow-name="xsl-region-body">
                                        <xsl:element name="fo:block">
                                                <!-- just a little extra
padding -->
                                                <xsl:attribute
name="border-width"><xsl:text>2em</xsl:text></xsl:attribute>
                                                <xsl:attribute
name="border-style"><xsl:text>none</xsl:text></xsl:attribute>
                                                <xsl:apply-templates/>
                                        </xsl:element>
                                </fo:flow>
                        </fo:page-sequence>
                </fo:root>
        </xsl:template>
                
        <xsl:template match="ws:p">
                <xsl:apply-templates select="ws:tab[1]"
mode="tab-handle"/>
                <xsl:apply-templates/>
        </xsl:template>
                                
        <xsl:template match="ws:b">
                <xsl:element name="fo:inline">
                        <xsl:attribute
name="font-weight"><xsl:text>bold</xsl:text></xsl:attribute>
                        <xsl:apply-templates/>
                </xsl:element>
        </xsl:template>
        
        <xsl:template match="ws:i">
                <xsl:element name="fo:inline">
                        <xsl:attribute
name="font-style"><xsl:text>italic</xsl:text></xsl:attribute>
                        <xsl:apply-templates/>
                </xsl:element>
        </xsl:template>
        
        
        <xsl:template match="ws:tab" mode="tab-handle">
                        <xsl:apply-templates
select="following-sibling::ws:br[1]" mode="tab-handle"/>
        </xsl:template>
        
        <xsl:template match="ws:br" mode="tab-handle">
                <xsl:variable name="number-of-columns">
                        <xsl:value-of
select="count(preceding-sibling::ws:tab)"/>
                </xsl:variable>
                <xsl:element name="fo:table">
                        <xsl:attribute name="width">
                                <xsl:text>100%</xsl:text>
                        </xsl:attribute>
                </xsl:element>
                <xsl:for-each select="preceding-sibling::ws:tab">
                <!-- Note the "first" preceding-sibling tab corresponds
to the          LAST fixed column in the table -->
                <!-- Formula: actual-column-number = # of
preceding-sibling tabs          minus (position() - 1) -->
                  <xsl:variable name="column-number"
select="$number-of-columns - (position() - 1)"/>
                  <xsl:variable name="column-width">
                                <!-- I want the $column-numberth item
from the parent::p/@tabs, minus the ($column-number - 1)th item - how
can I get that?? -->
                        </xsl:variable>
                        <fo:table-column
column-number="{$column-number}" width="${column-width}"/>
                </xsl:for-each>
                <!-- here I figure out the width of the final
column...-->
                <!-- but I can do that later. -->
        </xsl:template>
        
        <xsl:template match="ws:br">
                <!-- regular br tag -- empty block -->
                <fo:block/>
        </xsl:template>

</xsl:stylesheet>

As you might notice, my problem comes when trying to compute the width
of the table columns.  I have a formula for it, 

<!-- I want the $column-numberth item from the parent::p/@tabs, minus
the ($column-number - 1)th item - how can I get that?? -->

but can't figure out how to process the p/@tabs element to get the right
value for each column.  For column n I want the nth item - the (n-1)th
item.

Many thanks in advance for any help you can provide.

Sincerely,
Kyle Partridge


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list



<Prev in Thread] Current Thread [Next in Thread>