0
votes

I have an XSL-FO document. This document has a lot of fo:table nested. There is an inner fo:table that has 9 columns and a lot of rows, in this example, first row for table header and other rows, from 1 to 20 for content. In the example below you can see that as a comment, for each FOPTable (fo:table) it is indicated a unique identifier, but this identifier is not always the same for the same table. It is generated randomly by the application that creates this XSL-FO document.

My question is: I want to find the table which has its first column header value set to HEADER_COL1 (this value is always the same), in this example, table identified with id:997 (rember that I cannot search for table according to this identifier since it changes randomly each time application creates the XSL-FO document). Once I have found the desired table I want below:

  1. How can I insert an attribute break-before="page" for a concrete fo:table-row item?
  2. I want to get the number of rows that this inner table has.

For example:

For example, If I want to insert this attribute for the 15th fo:table-row item, how can I do this? I want a parametrized generic method that take as an argument a number indicating the fo:table-row where to put this attribute.

I know that I can read the XSL-FO document using below:

string xmlFile = File.ReadAllText(@"C:\Temp\MyXSLFO.xml");
XmlDocument xdoc = new XmlDocument();
xdoc.LoadXml(xmlFile);

But once loaded i have no idea on how to do this.

Note: I am using Visual Studio 2008, C# and .NET 3.5.

<?xml version="1.0" encoding="ISO-8859-1" ?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

<fo:page-sequence force-page-count="no-force" master-reference="first" initial-page-number="1">
<fo:flow flow-name="xsl-region-body">
<!--  begin table FOPTable { id: 987 cur_size: 28.7 prv_size: 20.0 prev: <none> cols: 2 locks: 2 flow:FOPFlow: { type: BodyFlow size:4 region:FOPRegion: { type:3 extent:0.0}} } 
  --> 
<fo:table font-size="8pt" font-family="sans-serif" space-before.optimum="0.05cm" table-layout="fixed">
</fo:table>
<!--  endof table id FOPTable { id: 987 cur_size: 28.7 prv_size: 20.0 prev: <none> cols: 2 locks: 5 flow:FOPFlow: { type: BodyFlow size:4 region:FOPRegion: { type:3 extent:0.0}} } 
  --> 
<!--  begin table FOPTable { id: 992 cur_size: 28.7 prv_size: 20.0 prev: <none> cols: 2 locks: 2 flow:FOPFlow: { type: BodyFlow size:3 region:FOPRegion: { type:3 extent:0.0}} } 
  --> 
<fo:table font-size="8pt" font-family="sans-serif" space-before.optimum="0.05cm" table-layout="fixed">
</fo:table>
<!--  endof table id FOPTable { id: 992 cur_size: 28.7 prv_size: 20.0 prev: <none> cols: 2 locks: 4 flow:FOPFlow: { type: BodyFlow size:3 region:FOPRegion: { type:3 extent:0.0}} } 
  --> 
<!--  begin table FOPTable { id: 995 cur_size: 28.7 prv_size: 0.0 prev: <none> cols: 2 locks: 2 flow:FOPFlow: { type: BodyFlow size:2 region:FOPRegion: { type:3 extent:0.0}} } 
  --> 
<fo:table font-size="8pt" font-family="sans-serif" space-before.optimum="0.05cm" table-layout="fixed">

<!--  begin table FOPTable { id: 996 cur_size: 0.0 prv_size: 20.41 prev: 995 cols: 1 locks: 2 flow:null } 
  --> 
<fo:table font-size="8pt" font-family="sans-serif" table-layout="fixed">

<!--  begin table FOPTable { id: 997 cur_size: 0.0 prv_size: 20.409999999999997 prev: 996 cols: 9 locks: 5 flow:null } 
  --> 
<fo:table font-size="8pt" font-family="sans-serif" table-layout="fixed">
  <fo:table-column column-width="2.87cm" /> 
  <fo:table-column column-width="2.87cm" /> 
  <fo:table-column column-width="2.87cm" /> 
  <fo:table-column column-width="4.709999999999996cm" /> 
  <fo:table-column column-width="2.87cm" /> 
  <fo:table-column column-width="3.9cm" /> 
  <fo:table-column column-width="2.87cm" /> 
  <fo:table-column column-width="2.87cm" /> 
  <fo:table-column column-width="2.87cm" /> 
<fo:table-header>
<fo:table-row>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
  <fo:block>HEADER_COL1</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
  <fo:block>HEADER_COL2</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
  <fo:block>HEADER_COL3</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
  <fo:block>HEADER_COL4</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
  <fo:block>HEADER_COL5</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
  <fo:block>HEADER_COL6</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
  <fo:block>HEADER_COL7</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
  <fo:block>HEADER_COL8</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
  <fo:block>HEADER_COL9</fo:block> 
  </fo:table-cell>
  </fo:table-row>
  </fo:table-header>
<fo:table-body>
<fo:table-row>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block>ROW1_COL1_VALUE</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block>ROW1_COL2_VALUE</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block>ROW1_COL3_VALUE</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block>ROW1_COL4_VALUE</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block>ROW1_COL5_VALUE</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block>ROW1_COL6_VALUE</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-right="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block text-align="end">ROW1_COL7_VALUE</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block>ROW1_COL8_VALUE</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block>ROW1_COL9_VALUE</fo:block> 
  </fo:table-cell>
  </fo:table-row>


<!-- A LOT OF ROWS HERE -->

<!-- I want to insert a break-before attribute as below -->
<fo:table-row break-before="page">
<!-- columns here -->
</fo:table-row>

<!-- MORE ROWS HERE -->

<!-- LAST ROW NEXT -->
<fo:table-row>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block>ROW20_COL1_VALUE</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block>ROW20_COL2_VALUE</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block>ROW20_COL3_VALUE</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block>ROW20_COL4_VALUE</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block>ROW20_COL5_VALUE</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block>ROW20_COL6_VALUE</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-right="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block text-align="end">ROW20_COL7_VALUE</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block>ROW20_COL8_VALUE</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block>ROW20_COL9_VALUE</fo:block> 
  </fo:table-cell>
  </fo:table-row>
  </fo:table-body>
  </fo:table>
<!--  endof table id FOPTable { id: 997 cur_size: 28.7 prv_size: 20.409999999999997 prev: 996 cols: 9 locks: 6 flow:null } 
  --> 
</fo:table>

</fo:table>

</fo:flow>
</fo:page-sequence>
</fo:root>
1
I would use XSLT. Since you're using VS2008, see w3.org/TR/1999/REC-xslt-19991116. You could make a template for your context that adds the attribute for the property, and make an identity template that copies the rest of the document to the result tree.Tony Graham
It seems overly complicated to nest tables 3 levels deep. Is this really necessary?Hobbes

1 Answers

0
votes

Taking your data and removing all the cells and other non-important content, one could simply apply an identity XSL to the XSL FO and modify only the target row.

starting with this XML:

<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

    <fo:page-sequence force-page-count="no-force" master-reference="first" initial-page-number="1">
        <fo:flow flow-name="xsl-region-body">
            <fo:table font-size="8pt" font-family="sans-serif" space-before.optimum="0.05cm" table-layout="fixed">
            </fo:table>
            <fo:table font-size="8pt" font-family="sans-serif" space-before.optimum="0.05cm" table-layout="fixed">
            </fo:table>
            <fo:table font-size="8pt" font-family="sans-serif" space-before.optimum="0.05cm" table-layout="fixed">
                <fo:table font-size="8pt" font-family="sans-serif" table-layout="fixed">
                    <fo:table font-size="8pt" font-family="sans-serif" table-layout="fixed">
                        <fo:table-column column-width="2.87cm" /> 
                        <fo:table-column column-width="2.87cm" /> 
                        <fo:table-column column-width="2.87cm" /> 
                        <fo:table-column column-width="4.709999999999996cm" /> 
                        <fo:table-column column-width="2.87cm" /> 
                        <fo:table-column column-width="3.9cm" /> 
                        <fo:table-column column-width="2.87cm" /> 
                        <fo:table-column column-width="2.87cm" /> 
                        <fo:table-column column-width="2.87cm" /> 
                        <fo:table-header>
                            <fo:table-row>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL1</fo:block> 
                                </fo:table-cell>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL2</fo:block> 
                                </fo:table-cell>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL3</fo:block> 
                                </fo:table-cell>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL4</fo:block> 
                                </fo:table-cell>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL5</fo:block> 
                                </fo:table-cell>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL6</fo:block> 
                                </fo:table-cell>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL7</fo:block> 
                                </fo:table-cell>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL8</fo:block> 
                                </fo:table-cell>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL9</fo:block> 
                                </fo:table-cell>
                            </fo:table-row>
                        </fo:table-header>
                        <fo:table-body>
                            <fo:table-row/>
                            <fo:table-row/>
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                        </fo:table-body>
                    </fo:table>
                </fo:table>

            </fo:table>

        </fo:flow>
    </fo:page-sequence>
</fo:root>

And applying this XSL which outputs everything as is, except for a template that inserts a page-break on the 12th row in the target table:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:fo="http://www.w3.org/1999/XSL/Format"
    version="2.0">
    <xsl:param name="breakrow" select="12"/>

    <xsl:template match="fo:table-row">
        <xsl:variable name="rowcnt" select="count(preceding-sibling::fo:table-row)"/>
        <xsl:choose>
            <xsl:when test="parent::fo:table-header">
                <fo:table-row>
                    <xsl:apply-templates/>
                </fo:table-row>
            </xsl:when>
            <xsl:when test="$rowcnt = $breakrow and ancestor::fo:table[1]/fo:table-header/fo:table-row[1]/fo:table-cell[1]/fo:block/text() = 'HEADER_COL1'">
                <fo:table-row break-before="page"/>
            </xsl:when>
            <xsl:otherwise>
                <fo:table-row/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:apply-templates select="node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

The result is this:

<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

    <fo:page-sequence force-page-count="no-force" master-reference="first" initial-page-number="1">
        <fo:flow flow-name="xsl-region-body">
            <fo:table font-size="8pt" font-family="sans-serif" space-before.optimum="0.05cm" table-layout="fixed">
            </fo:table>
            <fo:table font-size="8pt" font-family="sans-serif" space-before.optimum="0.05cm" table-layout="fixed">
            </fo:table>
            <fo:table font-size="8pt" font-family="sans-serif" space-before.optimum="0.05cm" table-layout="fixed">
                <fo:table font-size="8pt" font-family="sans-serif" table-layout="fixed">
                    <fo:table font-size="8pt" font-family="sans-serif" table-layout="fixed">
                        <fo:table-column column-width="2.87cm"/> 
                        <fo:table-column column-width="2.87cm"/> 
                        <fo:table-column column-width="2.87cm"/> 
                        <fo:table-column column-width="4.709999999999996cm"/> 
                        <fo:table-column column-width="2.87cm"/> 
                        <fo:table-column column-width="3.9cm"/> 
                        <fo:table-column column-width="2.87cm"/> 
                        <fo:table-column column-width="2.87cm"/> 
                        <fo:table-column column-width="2.87cm"/> 
                        <fo:table-header>
                            <fo:table-row>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL1</fo:block> 
                                </fo:table-cell>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL2</fo:block> 
                                </fo:table-cell>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL3</fo:block> 
                                </fo:table-cell>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL4</fo:block> 
                                </fo:table-cell>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL5</fo:block> 
                                </fo:table-cell>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL6</fo:block> 
                                </fo:table-cell>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL7</fo:block> 
                                </fo:table-cell>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL8</fo:block> 
                                </fo:table-cell>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border-width="0.5pt" border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL9</fo:block> 
                                </fo:table-cell>
                            </fo:table-row>
                        </fo:table-header>
                        <fo:table-body>
                            <fo:table-row/>
                            <fo:table-row/>
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row break-before="page"/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                        </fo:table-body>
                    </fo:table>
                </fo:table>

            </fo:table>

        </fo:flow>
    </fo:page-sequence>
</fo:root>

I passed in 12 as a parameter and assumed that you had only one place ... the 12th row. You can certainly use "mod" and do every 12th row or whatever you desire.

Like for instance:

 <xsl:when test="$rowcnt mod $breakrow = $breakrow - 1 and ancestor::fo:table[1]/fo:table-header/fo:table-row[1]/fo:table-cell[1]/fo:block/text() = 'HEADER_COL1'">

And of course you can just add to the rows to get all the cell content output.