You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-users@xmlgraphics.apache.org by Patrick <Pa...@hotmail.com> on 2006/08/10 16:43:56 UTC

Ending a row and starting a new one.

(I apologize if this is a duplicate message, but my first one does not appearing
to have been posted.)

I have a table that I need help with.  These are the steps that I need to do.

1.  Start a row.
2.  Add the first cell which will span multiple rows based on how many rows of
data are needed.
3.  Add a cell for each of the data elements.  For every fifth cell, I want to
start a new row.
4.  End the last row.

If this is my data:

<my_xml>
	<value>1</value>
	<value>2</value>
	<value>3</value>
	<value>4</value>
	<value>5</value>
	<value>6</value>
	<value>7</value>
	<value>8</value>
	<value>9</value>
	<value>10</value>
</my_xml>

This is how I want my row to look:

	<fo:table-row>
		<fo:table-cell number-rows-spanned="2">My Data</fo:table-cell>
		<fo:table-cell>1</fo:table-cell>
		<fo:table-cell>2</fo:table-cell>
		<fo:table-cell>3</fo:table-cell>
		<fo:table-cell>4</fo:table-cell>
		<fo:table-cell>5</fo:table-cell>
	</fo:table-row>
	<fo:table-row>
		<fo:table-cell>6</fo:table-cell>
		<fo:table-cell>7</fo:table-cell>
		<fo:table-cell>8</fo:table-cell>
		<fo:table-cell>9</fo:table-cell>
		<fo:table-cell>10</fo:table-cell>
	</fo:table-row>

I know how to do everything except how to end the old row and start a new one. 
I have a recursive xsl template that I'm calling to add each cell for the data.
 I can figure out whether the cell I'm on needs to start a new row.  I've done
this before to generate HTML using something like <xsl:text
disable-output-escaping="yes">&lt;/tr&gt;&lt;fo:tr&gt;</xsl:text>, but that
doesn't work going directly from XSL to FO to PDF.  I guess it would work if I
went from XSL to FO, reparsed the FO, then went to PDF, but I was hoping I could
do this all in one step.

I hope I'm making sense here.  This is difficult to explain.


---------------------------------------------------------------------
To unsubscribe, e-mail: fop-users-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-users-help@xmlgraphics.apache.org


Re: Ending a row and starting a new one.

Posted by Patrick <Pa...@hotmail.com>.
Once I switched to XSLT 2.0, I was able to get cells into the variable as a
node-set.  Unfortunately, for reasons that are too complicated to explain here,
I can't use XSLT 2.0.  It's fine though, because I figured out how to do it in
XSLT 1.0.

I realized that I should process the data as rows and then cells instead of just
cells.  I had already figured out how to calculate the number of rows, and the
number of columns was static.  I put a sample that I created below in case
anyone else needs the solution.  Please note that the sample may not be the best
way to do it, and it isn't complete.  I just did it as a test so that I could
prove that it could be done with my real data.

Here's is my XML (modified from what was above to show multiple records):

<my_xml>
  <data_set name="Data Set 1">
    <value>1</value>
    <value>2</value>
    <value>3</value>
    <value>4</value>
    <value>5</value>
    <value>6</value>
    <value>7</value>
  </data_set>
  <data_set name="Data Set 2">
    <value>8</value>
    <value>9</value>
    <value>10</value>
  </data_set>
</my_xml>

Here's my XSLT snippet:

<xsl:template match="/">
  <fo:table-body>
    <xsl:for-each select="/my_xml/data_set">
      <xsl:variable name="Data" select="current()"/>
      <xsl:variable name="Cols">5</xsl:variable>
      <xsl:variable name="Rows" select="ceiling(count($Data/value) div $Cols)"/>

      <xsl:call-template name="AddRows">
        <xsl:with-param name="Data" select="$Data"/>
        <xsl:with-param name="Cols" select="$Cols"/>
        <xsl:with-param name="Rows" select="$Rows"/>
        <xsl:with-param name="CurrRow">1</xsl:with-param>
        <xsl:with-param name="CurrCell">1</xsl:with-param>
      </xsl:call-template>
    </xsl:for-each>
  </fo:table-body>
</xsl:template>

<xsl:template name="AddRows">
  <xsl:param name="Data"/>
  <xsl:param name="Cols"/>
  <xsl:param name="Rows"/>
  <xsl:param name="CurrRow"/>
  <xsl:param name="CurrCell"/>

  <xsl:if test="$CurrRow &lt;= $Rows">
    <fo:table-row>
      <xsl:if test="$CurrRow=1">
        <xsl:element name="fo:table-cell">
          <xsl:if test="$Rows &gt; 1">
            <xsl:attribute name="number-rows-spanned"><xsl:value-of
select="$Rows"/></xsl:attribute>
          </xsl:if>
          <fo:block>
            <xsl:value-of select="$Data/@name"/>
          </fo:block>
        </xsl:element>
      </xsl:if>

      <xsl:call-template name="AddCells">
        <xsl:with-param name="Data" select="$Data"/>
        <xsl:with-param name="Cols" select="$Cols"/>
        <xsl:with-param name="CurrRow" select="$CurrRow"/>
        <xsl:with-param name="CurrCell" select="$CurrCell"/>
      </xsl:call-template>
    </fo:table-row>

    <xsl:call-template name="AddRows">
      <xsl:with-param name="Data" select="$Data"/>
      <xsl:with-param name="Cols" select="$Cols"/>
      <xsl:with-param name="Rows" select="$Rows"/>
      <xsl:with-param name="CurrRow" select="$CurrRow+1"/>
      <xsl:with-param name="CurrCell" select="$CurrCell + $Cols"/>
    </xsl:call-template>
  </xsl:if>
</xsl:template>

<xsl:template name="AddCells">
  <xsl:param name="Data"/>
  <xsl:param name="Cols"/>
  <xsl:param name="CurrRow"/>
  <xsl:param name="CurrCell"/>

  <xsl:if test="$CurrCell &lt;= ($CurrRow * $Cols)">
    <fo:table-cell>
      <fo:block>
        <xsl:choose>
          <xsl:when test="count($Data/value[position()=$CurrCell])=1">
            <xsl:value-of select="$Data/value[position()=$CurrCell]"/>
          </xsl:when>
          <xsl:otherwise>(spacer cell)</xsl:otherwise>
        </xsl:choose>
      </fo:block>
    </fo:table-cell>

    <xsl:call-template name="AddCells">
      <xsl:with-param name="Data" select="$Data"/>
      <xsl:with-param name="Cols" select="$Cols"/>
      <xsl:with-param name="CurrRow" select="$CurrRow"/>
      <xsl:with-param name="CurrCell" select="$CurrCell + 1"/>
    </xsl:call-template>
  </xsl:if>
</xsl:template>



---------------------------------------------------------------------
To unsubscribe, e-mail: fop-users-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-users-help@xmlgraphics.apache.org


Re: Ending a row and starting a new one.

Posted by Jay Bryant <ja...@bryantcs.com>.
Hi, Patrick,

I use XSLT 2.0 all the time, so I assume that everyone does. My bad.

You can use XSLT 2.0 with FOP, thus:

1. Use your XSLT 2.0 processor to create an FO file.

2. Then feed the FO file to FOP.

For example, suppose you use Saxon 8 (as I do) for for your XLST processor
and that it's installed off the root directory. Then you'd get two command
lines that look like this:

java -jar \saxon\saxon8.jar -o myfile.fo myinput.xml something-to-fo.xsl
fop myfile.fo myfile.pdf

That combination would turn myinput.xml into myfile.pdf.

I have a whole pile of batch files and Ant tasks to run that process on all
kinds of input files.

HTH

Jay Bryant
Bryant Communication Services

----- Original Message ----- 
From: "Patrick" <Pa...@hotmail.com>
To: <fo...@xmlgraphics.apache.org>
Sent: Thursday, August 10, 2006 1:23 PM
Subject: Re: Ending a row and starting a new one.


> I'm trying to follow your suggestion, but this is where I'm stuck:
>
> > <xsl:variable name="cells">
> >   <xsl:call-template name="your-template"/>
> > </xsl:variable>
>
> The variable "cells" contains the correct data as returned by my template
but
> not as a node-set, so I can't act on it as such.  I ran into this before
when I
> was trying to get something else to work.  I think the problem may be that
I'm
> using XSLT 1.0/XPath 1.0.  If I have to use 2.0, will that work with
Apache FOP
> 0.20.5?
>
> Thanks.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: fop-users-unsubscribe@xmlgraphics.apache.org
> For additional commands, e-mail: fop-users-help@xmlgraphics.apache.org
>



---------------------------------------------------------------------
To unsubscribe, e-mail: fop-users-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-users-help@xmlgraphics.apache.org


Re: Ending a row and starting a new one.

Posted by Perez <ar...@ethicist.net>.
In article <lo...@post.gmane.org>,
 Patrick <Pa...@hotmail.com> wrote:

> I'm trying to follow your suggestion, but this is where I'm stuck:
> 
> > <xsl:variable name="cells">
> >   <xsl:call-template name="your-template"/>
> > </xsl:variable>
> 
> The variable "cells" contains the correct data as returned by my template but
> not as a node-set, so I can't act on it as such.  I ran into this before when 
> I
> was trying to get something else to work.  I think the problem may be that 
> I'm
> using XSLT 1.0/XPath 1.0.  If I have to use 2.0, will that work with Apache 
> FOP
> 0.20.5?
> 
> Thanks.

Many vendors provide a nodeset extension.  I know xalan does.  In that 
case you do do a <xalan:nodeset select="$cells/xyx"/> or some such.

-arturo


---------------------------------------------------------------------
To unsubscribe, e-mail: fop-users-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-users-help@xmlgraphics.apache.org


Re: Ending a row and starting a new one.

Posted by Patrick <Pa...@hotmail.com>.
I'm trying to follow your suggestion, but this is where I'm stuck:

> <xsl:variable name="cells">
>   <xsl:call-template name="your-template"/>
> </xsl:variable>

The variable "cells" contains the correct data as returned by my template but
not as a node-set, so I can't act on it as such.  I ran into this before when I
was trying to get something else to work.  I think the problem may be that I'm
using XSLT 1.0/XPath 1.0.  If I have to use 2.0, will that work with Apache FOP
0.20.5?

Thanks.


---------------------------------------------------------------------
To unsubscribe, e-mail: fop-users-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-users-help@xmlgraphics.apache.org


Re: Ending a row and starting a new one.

Posted by Jay Bryant <ja...@bryantcs.com>.
Hi, Patrick,

Before I show one possible solution, let me suggest that you subscribe to
Mulberry's XSL List [1] and ask this question there. Also, avoid
disable-output-escaping like the plague; it's bad practice. Ask the list or
look at Dave Pawson's FAQ [2] for why.

If you always want two rows, your problem is fairly easy to solve.

First, use your recursive template to write all the cells into a variable,
thus:

<xsl:variable name="cells">
  <xsl:call-template name="your-template"/>
</xsl:variable>

Then you can put the first half into one row and the second half into
another, thus:

<xsl:variable name="halfway" select="count($cells) div 2"/>
<fo:table-row>
  <xsl:copy-of select="$cells[position() &lt; $halfway + 1"/>
</fo:table-row>
<fo:table-row>
  <xsl:copy-of select="$cells[position() &gt; $halfway"/>
</fo:table-row>

You may need to fiddle with this some to get it to work, but it's one
solution.

The real fun comes when you have a variable number of columns, but that can
be solved, too. For now, I'll assume you have the simple version of the
problem.

[1] http://www.mulberrytech.com/xsl/xsl-list/
[2] http://www.dpawson.co.uk/xsl/index.html

Jay Bryant
Bryant Communication Services

----- Original Message ----- 
From: "Patrick" <Pa...@hotmail.com>
To: <fo...@xmlgraphics.apache.org>
Sent: Thursday, August 10, 2006 9:43 AM
Subject: Ending a row and starting a new one.


> (I apologize if this is a duplicate message, but my first one does not
appearing
> to have been posted.)
>
> I have a table that I need help with.  These are the steps that I need to
do.
>
> 1.  Start a row.
> 2.  Add the first cell which will span multiple rows based on how many
rows of
> data are needed.
> 3.  Add a cell for each of the data elements.  For every fifth cell, I
want to
> start a new row.
> 4.  End the last row.
>
> If this is my data:
>
> <my_xml>
> <value>1</value>
> <value>2</value>
> <value>3</value>
> <value>4</value>
> <value>5</value>
> <value>6</value>
> <value>7</value>
> <value>8</value>
> <value>9</value>
> <value>10</value>
> </my_xml>
>
> This is how I want my row to look:
>
> <fo:table-row>
> <fo:table-cell number-rows-spanned="2">My Data</fo:table-cell>
> <fo:table-cell>1</fo:table-cell>
> <fo:table-cell>2</fo:table-cell>
> <fo:table-cell>3</fo:table-cell>
> <fo:table-cell>4</fo:table-cell>
> <fo:table-cell>5</fo:table-cell>
> </fo:table-row>
> <fo:table-row>
> <fo:table-cell>6</fo:table-cell>
> <fo:table-cell>7</fo:table-cell>
> <fo:table-cell>8</fo:table-cell>
> <fo:table-cell>9</fo:table-cell>
> <fo:table-cell>10</fo:table-cell>
> </fo:table-row>
>
> I know how to do everything except how to end the old row and start a new
one.
> I have a recursive xsl template that I'm calling to add each cell for the
data.
>  I can figure out whether the cell I'm on needs to start a new row.  I've
done
> this before to generate HTML using something like <xsl:text
> disable-output-escaping="yes">&lt;/tr&gt;&lt;fo:tr&gt;</xsl:text>, but
that
> doesn't work going directly from XSL to FO to PDF.  I guess it would work
if I
> went from XSL to FO, reparsed the FO, then went to PDF, but I was hoping I
could
> do this all in one step.
>
> I hope I'm making sense here.  This is difficult to explain.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: fop-users-unsubscribe@xmlgraphics.apache.org
> For additional commands, e-mail: fop-users-help@xmlgraphics.apache.org
>



---------------------------------------------------------------------
To unsubscribe, e-mail: fop-users-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-users-help@xmlgraphics.apache.org


Re: Ending a row and starting a new one.

Posted by Patrick <Pa...@hotmail.com>.
That might work, but according to the web site, "starts-row" and "ends-row"
aren't supported in FOP 0.20.5.  That's the version I have to use for right now.


---------------------------------------------------------------------
To unsubscribe, e-mail: fop-users-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-users-help@xmlgraphics.apache.org


RE: Ending a row and starting a new one.

Posted by Rick Roen <Ri...@LakeValleySeed.com>.
You can skip the <fo:table-row> and use <fo:table-cell starts-row="true">
for the first row and <fo:table-cell ends-row="true"> for the last row.

Now to get this information:  

...xslt
<fo:table-cell>
	<xsl:choose>
		<xsl:when test="pos(.) eq 1"><xsl:attribute
select="starts-row">true</xsl:when>
...

The test for the last column would be test="pos(.) mod 5 eq 0" .

HTH,

Rick



If this is my data:

<my_xml>
	<value>1</value>
	<value>2</value>
	<value>3</value>
	<value>4</value>
	<value>5</value>
	<value>6</value>
	<value>7</value>
	<value>8</value>
	<value>9</value>
	<value>10</value>
</my_xml>

This is how I want my row to look:

	<fo:table-row>
		<fo:table-cell number-rows-spanned="2">My
Data</fo:table-cell>
		<fo:table-cell>1</fo:table-cell>
		<fo:table-cell>2</fo:table-cell>
		<fo:table-cell>3</fo:table-cell>
		<fo:table-cell>4</fo:table-cell>
		<fo:table-cell>5</fo:table-cell>
	</fo:table-row>
	<fo:table-row>
		<fo:table-cell>6</fo:table-cell>
		<fo:table-cell>7</fo:table-cell>
		<fo:table-cell>8</fo:table-cell>
		<fo:table-cell>9</fo:table-cell>
		<fo:table-cell>10</fo:table-cell>
	</fo:table-row>

I know how to do everything except how to end the old row and start a new
one. 


---------------------------------------------------------------------
To unsubscribe, e-mail: fop-users-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-users-help@xmlgraphics.apache.org