templateslayoutprintingxsl-fopage-numbering

XSL-FO how to propagate page numbering from template to another


It is my first experience in XSL-FO printing.

There are 2 templates each has its own layout.xsl

It is needed to edit the page numbering of second template to be successor to the first one.

Example

template one has 4 pages, then template two should start by page no. 5 not 1!

I have an ideas but still doesn't work; is to create a 3rd template that call these 2 templates

<xsl:template>
        <xsl:call-template name="templateOne" />
        <!-- <xsl:block break-after="page"/> -->
        <xsl:call-template name="templateTwo" />
        <!-- <xsl:block break-after="page"/> -->
</xsl:template>

Layout of templateOne:

<xsl:template match="/">
        <fo:root>       
            <xsl:call-template name="LayoutMasterSet"/>
            <xsl:variable name="TheVeryLastPage" select="."/>
            <xsl:choose>
                <xsl:when test="$titel='Anwendungsprotokoll'">
                    <fo:page-sequence master-reference="landscape" initial-page-number="1" format="1">
                        <!-- Kopfzeile -->
                        <xsl:call-template name="StandardKopfzeile">
                            <xsl:with-param name="TheVeryLastPage"><xsl:value-of select="$TheVeryLastPage"/></xsl:with-param>
                        </xsl:call-template>
                        <!-- Fusszeile -->
                        <xsl:call-template name="StandardFusszeile">
                            <xsl:with-param name="TheVeryLastPage"><xsl:value-of select="$TheVeryLastPage"/></xsl:with-param>
                        </xsl:call-template>
                        <fo:flow flow-name="xsl-region-body">
                            <fo:block font-size="8pt" line-height="10pt">
                                <xsl:apply-templates select="/*"/>
                            </fo:block>
                            <fo:block id="{generate-id($TheVeryLastPage)}"/>
                        </fo:flow>
                    </fo:page-sequence>
                </xsl:when>
                <xsl:otherwise>
                    <fo:page-sequence master-reference="default-pages" initial-page-number="1" format="1">
                        <!-- Kopfzeile -->
                        <xsl:call-template name="StandardKopfzeile">
                            <xsl:with-param name="TheVeryLastPage"><xsl:value-of select="$TheVeryLastPage"/></xsl:with-param>
                        </xsl:call-template>
                        <!-- Fusszeile -->
                        <xsl:call-template name="StandardFusszeile">
                            <xsl:with-param name="TheVeryLastPage"><xsl:value-of select="$TheVeryLastPage"/></xsl:with-param>
                        </xsl:call-template>
                        <fo:flow flow-name="xsl-region-body">
                            <fo:block font-size="8pt" line-height="10pt">
                                <xsl:apply-templates select="/*"/>
                            </fo:block>
                            <fo:block id="{generate-id($TheVeryLastPage)}"/>
                        </fo:flow>
                    </fo:page-sequence>
                </xsl:otherwise>
            </xsl:choose>
        </fo:root>
    </xsl:template>

Layout of templateTwo:

<xsl:template match="/">
        <fo:root xsl:use-attribute-sets="font.arial.8.normal.black">
            <xsl:call-template name="LayoutMasterSet"/>
            <xsl:variable name="TheVeryLastPage" select="."/>
            <fo:page-sequence master-reference="default-pages" initial-page-number="1" format="1">
                <xsl:call-template name="StandardHeader"/>
                <xsl:call-template name="GeneralFooter">
                    <xsl:with-param name="TheVeryLastPage">
                        <xsl:value-of select="$TheVeryLastPage"/>
                    </xsl:with-param>
                </xsl:call-template>
                <xsl:apply-templates select="/*"/>
            </fo:page-sequence>
        </fo:root>
    </xsl:template>
    <!-- ++++++++++++++++++++++++++++++++++Layout Master Set+++++++++++++++++++++++++++++++++++++++++++++ -->
    <xsl:template name="LayoutMasterSet">
        <fo:layout-master-set>
            <fo:simple-page-master master-name="any-page" page-height="297mm" page-width="210mm" margin-top="1.5cm" margin-bottom="1.5cm" margin-left="1.5cm" margin-right="1.5cm">
                <fo:region-body margin-top="2cm" margin-bottom="2cm" column-count="{$columns}"/>
                <fo:region-before extent="2cm" region-name="region-before"/>
                <fo:region-after extent="2cm" region-name="region-after"/>
            </fo:simple-page-master>
            <fo:page-sequence-master master-name="default-pages">
                <fo:repeatable-page-master-alternatives>
                    <fo:conditional-page-master-reference page-position="any" master-reference="any-page"/>
                </fo:repeatable-page-master-alternatives>
            </fo:page-sequence-master>
        </fo:layout-master-set>
    </xsl:template>

This idea doesn't work, it gives me:

saving .xsl. <anonymous development build> javax.xml.transform.TransformerException: org.apache.fop.fo.ValidationException: "{http://www.w3.org/1999/XSL/Format}table" is not a valid child of "fo:page-sequence"!

ERROR |17:33:05,752|DefaultExceptionHandler.logException:75 (WorkerThread 17:31:48)[-1] TRANSFORMATION_ERROR [] <anonymous development build>
de.vodafone.core.exception.BadProcessingException: [-1] TRANSFORMATION_ERROR []
    at de.vodafone.app.epos.shared.print.fop.FopPrintService.addToPageable(FopPrintService.java:165)
    at de.vodafone.app.epos.shared.print.fop.FopPrintService.print(FopPrintService.java:78)
    at de.vodafone.app.epos.shared.print.fop.PrintServiceDelegator.print(PrintServiceDelegator.java:53)
    at de.vodafone.app.epos.shared.print.activity.AbstractPrintAgent.execute(AbstractPrintAgent.java:213)
    at de.vodafone.app.epos.shared.activity.ActivityManager.execute(ActivityManager.java:78)
    at de.vodafone.app.epos.client.plugin.order.manager.common.presentation.AbstractOrderFacade.executeActivities(AbstractOrderFacade.java:210)
    at de.vodafone.app.epos.client.plugin.order.manager.common.presentation.SingleCustomerOrderFacade.handleAfterSave(SingleCustomerOrderFacade.java:101)
    at de.vodafone.app.epos.client.plugin.fixednet.activation.mvc.FNActivationFacade.handleAfterSave(FNActivationFacade.java:370)
    at de.vodafone.app.epos.client.plugin.order.manager.common.presentation.AbstractOrderFacade.save(AbstractOrderFacade.java:335)
    at de.vodafone.app.epos.client.plugin.order.manager.common.presentation.AbstractOrderFacade.save(AbstractOrderFacade.java:298)
    at de.vodafone.app.epos.client.plugin.order.manager.common.presentation.AbstractOrderFacade.send(AbstractOrderFacade.java:117)
    at de.vodafone.app.epos.client.plugin.order.manager.common.presentation.AbstractOrderController.send(AbstractOrderController.java:943)
    at de.vodafone.app.epos.client.plugin.order.manager.common.presentation.AbstractOrderController.onSend(AbstractOrderController.java:861)
    at de.vodafone.app.epos.client.plugin.order.manager.common.presentation.AbstractOrderController$10.doExecuteCommand(AbstractOrderController.java:1258)
    at de.vodafone.app.epos.client.framework.ui.action.AbstractWidgetActionUIJob.execute(AbstractWidgetActionUIJob.java:45)
    at de.vodafone.app.epos.client.framework.ui.action.RunnableBuilder$CommandRunnable.run(RunnableBuilder.java:196)
    at de.vodafone.app.epos.client.framework.ui.action.AbstractUIJob.run(AbstractUIJob.java:50)
    at EDU.oswego.cs.dl.util.concurrent.QueuedExecutor$RunLoop.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:748)
Caused by: javax.xml.transform.TransformerException: org.apache.fop.fo.ValidationException: "{http://www.w3.org/1999/XSL/Format}table" is not a valid child of "fo:page-sequence"! (Siehe Position 17:276)
    at org.apache.xalan.transformer.TransformerIdentityImpl.transform(TransformerIdentityImpl.java:469)
    at de.vodafone.app.epos.shared.print.fop.FopPrintService.addToPageable(FopPrintService.java:156)
    ... 18 more
Caused by: org.apache.fop.fo.ValidationException: "{http://www.w3.org/1999/XSL/Format}table" is not a valid child of "fo:page-sequence"! (Siehe Position 17:276)
    at org.apache.fop.events.ValidationExceptionFactory.createException(ValidationExceptionFactory.java:38)
    at org.apache.fop.events.EventExceptionManager.throwException(EventExceptionManager.java:54)
    at org.apache.fop.events.DefaultEventBroadcaster$1.invoke(DefaultEventBroadcaster.java:175)
    at com.sun.proxy.$Proxy1.invalidChild(Unknown Source)
    at org.apache.fop.fo.FONode.invalidChildError(FONode.java:534)
    at org.apache.fop.fo.FONode.invalidChildError(FONode.java:517)
    at org.apache.fop.fo.pagination.PageSequence.validateChildNode(PageSequence.java:147)
    at org.apache.fop.fo.FOTreeBuilder$MainFOHandler.startElement(FOTreeBuilder.java:267)
    at org.apache.fop.fo.FOTreeBuilder.startElement(FOTreeBuilder.java:171)
    at org.apache.xalan.transformer.TransformerIdentityImpl.startElement(TransformerIdentityImpl.java:1020)
    at org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown Source)
    at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
    at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
    at org.apache.xalan.transformer.TransformerIdentityImpl.transform(TransformerIdentityImpl.java:452)
    ... 19 more

Cause I am not the one that write these huge templates, I couldn't find the bad location of fo:table inside fo:page-sequence

Moreover, the page number is not propagated. I think to define a param that initially by 1 and setted by the last page of templateOne to be incremented by 1 and initialized the first page of Template 2 just after fixing the previous formation exception.

Your help is really appricated Thanks a lot Mariam


Solution

  • To solve the fo:table problem, you need an fo:flow inside your fo:page-sequence (see https://www.w3.org/TR/xsl11/#fo_page-sequence). templateOne has it (but the properties on the fo:block inside the fo:flow could be put on the fo:flow and the fo:block could be omitted). templateTwo does not have an fo:flow inside its fo:page-sequence.

    Your other problem is that both templates create an fo:root. fo:root is, as the name implies, the root of the FO document. Since the FO document that you are generating is also an XML document, the document can only have one 'document' element, i.e., one fo:root.

    Please see this diagram from Section 6.4.1.6, Pagination Tree Structure, of the XSL 1.1 Recommendation (https://www.w3.org/TR/xsl11/#d0e7181)

    Pagination tree structure diagram from https://www.w3.org/TR/xsl11/#d0e7181

    However, the diagram fails to show that fo:root may contain multiple fo:page-sequence (see https://www.w3.org/TR/xsl11/#fo_root).

    To get templateOne and templateTwo to work together, you should generate one fo:root and one fo:layout-master-set and have templateOne and templateTwo generate content starting at the fo:page-sequence level. Something like:

    fo:root
      fo:layout-master-set
      fo:page-sequence (generated by templateOne)
      fo:page-sequence (generated by templateTwo)
    

    If you do all that, then you will have solved the question in the title. The default value for the initial-page-number property (see https://www.w3.org/TR/xsl11/#initial-page-number) on each fo:page-sequence will make the second fo:page-sequence start with the page number after the last page number of the previous fo:page-sequence.

    Another lurking problem is that both templateOne and templateTwo include:

    <xsl:apply-templates select="/*"/>
    

    If you are processing one source document, then you are going to get two copies of your content. We can't help you with that unless we know more about the structure of the XML that you are trying to process.