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 Sven Waibel <sv...@imbus.de> on 2004/09/01 10:48:14 UTC

Pagebreak

Hello,

i've a problem with break-after="page" respectively break-before="page".

I always get an empty page either before my content starts or after the content.

first page | empty page | content | content | last page
or
first page | content | content | empty page |last page

That's consistent, but how can i achieve that no empty pages exist?

Regards
Sven

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


Re: Pagebreak

Posted by Abel Braaksma <ab...@xs4all.nl>.
paul wrote:
> oh my gosh, I just noticed a huge mistake on my part. My first page actually has
> never been blank, but there was a tiny text on there. unwanted text, for some
> xpath-mistake on my side it got printed too. So I guess with my for-each loop I
> managed to avoid printing this text and therefore avoided the first pagebreak
> with an almost empty page. I'm sorry for unnecessary posting, hope I didn't
> steal too much of your time. Still learning...

Your best bet for questions on XSLT is the XSLT list.

The reason for this text is likely the following: the default template 
for any content is the same as the xsl:value-of, which extracts the 
text. If you fail to supply a root template match, it is likely that for 
missed template matches, the default template is called. Consider:

<a>
    text
    <b>other text</b<
</a>

The following stylesheet will output both "text" and "other text":

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
version="1.0">
</xsl:stylesheet>

The following stylesheet will so too, because it only matches "b" nodes 
with "a" as parent. The "a" node does not have a match and so will fall 
into the default template:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
version="1.0">
   <xsl:template match="a/b">
       <xsl:value-of select="." />
   </xsl:template>
</xsl:stylesheet>

The following stylesheet will only print "other text":

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
version="1.0">
   <xsl:stylesheet match="/">
       <xsl:apply-templates select="a/b" />
   </xsl:stylesheet>
   <xsl:template match="b">
       <xsl:value-of select="." />
   </xsl:template>
</xsl:stylesheet>


When nodes do not contain bare text but only child nodes and attributes, 
this is not a problem. However, this is seldom the case (consider 
whitespace nodes, they are almost always there) and so it is good 
practice to start a new template using the root match and go from there.

Cheers,
-- Abel Braaksma
   http://www.nuntia.nl

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


Re: Pagebreak

Posted by paul <sa...@gmx.ch>.
oh my gosh, I just noticed a huge mistake on my part. My first page actually has
never been blank, but there was a tiny text on there. unwanted text, for some
xpath-mistake on my side it got printed too. So I guess with my for-each loop I
managed to avoid printing this text and therefore avoided the first pagebreak
with an almost empty page. I'm sorry for unnecessary posting, hope I didn't
steal too much of your time. Still learning...


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


Re: Pagebreak

Posted by Abel Braaksma <ab...@xs4all.nl>.
paul wrote:

> I chose to do
>
> <xsl:template match="a/b">
> <xsl:for-each select="c">
> <fo:block break-before="page">
> (content)
> </fo:block>
> </xsl:for-each>
> </xsl:templat

Hi Paul

I'm glad it worked out. In the xslt language it is usually best to let 
the processor do the work for you. Often people choose to use 
xsl:choose, xsl:if and xsl:for-each when a pure template approach would 
suffice. You can rewrite the above as follows:

<xsl:template match="a">
    <xsl:apply-templates select="b/c" />
</xsl:template>

<xsl:template match="c">
    <fo:block break-before="page">
         <xsl:apply-templates select="yourcontent" />
     </fo:block>
</xsl:template>

<xsl:template match="yourcontent">
     ...blocks for your content etc...
</xsl:template>


Trying to think XSLT and to consider using declarative style (xslt is a 
declarative programming language, as opposed to imperative, which is the 
type for Java, C#, VB etc; within declarative languages, you tell what 
you want and the processor defines the best execution path and decision 
logic), will increase your joy with the language and your speed of 
programming.

Cheers,
-- Abel Braaksma
   http://www.nuntia.nl

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


Re: Pagebreak

Posted by paul <sa...@gmx.ch>.
Abel, J.Pietschmann, thank you both very much for your detailed help, you
brought me back on the tracks and I've learned much new!

I found a forth solution that works well for me and could be a solution for
others complaining about the problem of unwanted blank pages when inserting
pagebreaks using break-before="page":

instead of:

<xsl:template match="a/b/c">
<xsl:if test="position() > 1"><fo:block break-before="page"/></xsl:if>
<fo:block>
(content)
</fo:block>
</xsl:for-each>
</xsl:template


I chose to do

<xsl:template match="a/b">
<xsl:for-each select="c">
<fo:block break-before="page">
(content)
</fo:block>
</xsl:for-each>
</xsl:template

This way, FOP automatically seems to recognise, that for the very first element
"c" there is no page-break needed. A test for the position is not needed. It may
not be applicable in all situations, but for me this works perfect.


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


Re: Pagebreak

Posted by Abel Braaksma <ab...@xs4all.nl>.
paul wrote:
> somehow it doesn't work for me :( I suspect I have an xpath-problem, but can't
> figure out what would be wrong...
>
> my template starts like this:
> <xsl:template match="projektindikator_info/projekt/projektindikator">
> 	<xsl:if test="position() > 1"><fo:block break-before="page"/></xsl:if>
>
> ...
>
> it works just fine, but always inserts a blank page at the beginning of the
> document. I don't understand this. Can I only call for positions if I go through
> a for-each loop?
>   

This is an XSLT question and not about fop. You'll have more luck on the 
XSLT list. But to answer your question: position() returns the position 
of the current node in the source tree. It can be used inside an 
xsl:template (like you do) and in an xsl:for-each, xsl:for-each-group 
(if you use XSLT 2) etc.

You say "my template starts like this", but XSLT is a declarative 
language, the order of elements is not important, so it is impossible to 
say anything useful about your template without seeing more. Create a 
smallest possible XSLT file and a smallest possible XML input file that 
illustrate your problem. Post them, plus explanation and an example of 
what you want the output to look like, on the XSLT list and you have a 
good chance that someone can help you out.

Cheers,
-- Abel Braaksma

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


Re: Pagebreak

Posted by Abel Braaksma <ab...@xs4all.nl>.
J.Pietschmann wrote:
> There are two possibilities:
> 1. Use <xsl:strip-space elements="*"/>, or whatever suits you.
> 2. Use <xsl:apply-templates select="*"/> or something similar at
>  the necessary places, which will apply templates to element nodes only
>  and ignore all text nodes.

And a third: use <xsl:number /> inside your match, like this (puts '1' 
to the result tree, while position() would put '2'):

    <xsl:template match="b">
        <xsl:variable name="nr"><xsl:number /></xsl:variable>
        <xsl:value-of select="$nr"/>
    </xsl:template>


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


Re: Pagebreak

Posted by "J.Pietschmann" <j3...@yahoo.de>.
paul wrote:
> somehow it doesn't work for me :( I suspect I have an xpath-problem, but can't
> figure out what would be wrong...
> 
> my template starts like this:
> <xsl:template match="projektindikator_info/projekt/projektindikator">
> 	<xsl:if test="position() > 1"><fo:block break-before="page"/></xsl:if>
> 
> ...
> 
> it works just fine, but always inserts a blank page at the beginning of the
> document. I don't understand this.

It looks like the position is always >1, contrary to what you expect.
This is a common symptom for discounting invisible but still relevant
parts of the source: whitespace.

If you have
  <a>
    <b>stuff</b>
  </a>

and
  <xsl:template match="b">
   <xsl:value select="position()>1"/>
  </xsl:template>

it will always print true, because there is a text node containing
a line feed an a few spaces right before the b element node.

There are two possibilities:
1. Use <xsl:strip-space elements="*"/>, or whatever suits you.
2. Use <xsl:apply-templates select="*"/> or something similar at
  the necessary places, which will apply templates to element nodes only
  and ignore all text nodes.

J.Pietschmann

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


Re: Pagebreak

Posted by paul <sa...@gmx.ch>.
somehow it doesn't work for me :( I suspect I have an xpath-problem, but can't
figure out what would be wrong...

my template starts like this:
<xsl:template match="projektindikator_info/projekt/projektindikator">
	<xsl:if test="position() > 1"><fo:block break-before="page"/></xsl:if>

...

it works just fine, but always inserts a blank page at the beginning of the
document. I don't understand this. Can I only call for positions if I go through
a for-each loop?

cheers, pl




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


Re: Pagebreak

Posted by Sven Waibel <sv...@imbus.de>.
Thanks Holger,
that's working for me.

Sven

Holger Dehnhardt wrote:

> Sven,
> 
> <xsl:if test="position() > 1">
> 	<fo:block break-before="page"/>
> </xsl:if>
> 
> should do the trick. If anyone has a better solution, I would appreciate it.
> 
> Holger
> 
> Am Mittwoch, 1. September 2004 10:48 schrieb Sven Waibel:
> 
>>>Hello,
>>>
>>>i've a problem with break-after="page" respectively break-before="page".
>>>
>>>I always get an empty page either before my content starts or after the
>>>content.
>>>
>>>first page | empty page | content | content | last page
>>>or
>>>first page | content | content | empty page |last page
>>>
>>>That's consistent, but how can i achieve that no empty pages exist?
>>>
>>>Regards
>>>Sven
>>>
>>>---------------------------------------------------------------------
>>>To unsubscribe, e-mail: fop-user-unsubscribe@xml.apache.org
>>>For additional commands, e-mail: fop-user-help@xml.apache.org
> 

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




-- 
**************************************************************************
* Sven Waibel					imbus AG		 *	
* Tel:     09131/7518-36			Kleinseebacher Str.9	 *
* Fax:     09131/7518-50			91096 Möhrendorf	 *
* EMail:   Sven.Waibel@imbus.de			WWW: http://www.imbus.de *
**************************************************************************

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


Re: Pagebreak

Posted by Holger Dehnhardt <de...@lehmanns.de>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Sven,

<xsl:if test="position() > 1">
	<fo:block break-before="page"/>
</xsl:if>

should do the trick. If anyone has a better solution, I would appreciate it.

Holger

Am Mittwoch, 1. September 2004 10:48 schrieb Sven Waibel:
> Hello,
>
> i've a problem with break-after="page" respectively break-before="page".
>
> I always get an empty page either before my content starts or after the
> content.
>
> first page | empty page | content | content | last page
> or
> first page | content | content | empty page |last page
>
> That's consistent, but how can i achieve that no empty pages exist?
>
> Regards
> Sven
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: fop-user-unsubscribe@xml.apache.org
> For additional commands, e-mail: fop-user-help@xml.apache.org
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)

iD8DBQFBNaqm1ZVW9AajbE4RAiC3AJsF1ocaBcJT6498q3HV6KelsXu3OwCfQkM5
epniIq5r3df3D+Wws4W0tPI=
=dGk3
-----END PGP SIGNATURE-----

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