XSL-FO, как распространить нумерацию страниц из шаблона в другой

Это мой первый опыт печати XSL-FO.

Есть 2 шаблона, у каждого свой layout.xsl

Необходимо отредактировать нумерацию страниц второго шаблона, чтобы он стал преемником первого.

Пример

первый шаблон имеет 4 страницы, тогда второй шаблон должен начинаться с номера страницы. 5 не 1!

У меня есть идеи, но они все еще не работают; заключается в создании 3-го шаблона, который вызывает эти 2 шаблона

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

Макет 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>

Макет 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>

Эта идея не работает, она дает мне:

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

Потому что я не тот, кто пишет эти огромные шаблоны, я не мог найти плохое расположение fo:table внутри fo:page-sequence.

При этом номер страницы не распространяется. Я думаю определить параметр, который изначально равен 1 и установлен последней страницей templateOne, чтобы увеличиться на 1 и инициализировать первую страницу Template 2 сразу после исправления предыдущего исключения формирования.

Ваша помощь очень важна. Большое спасибо, Мариам.


person Mariam A. Moustafa    schedule 19.02.2020    source источник
comment
Вы пытаетесь создать один документ PDF или два документа?   -  person Tony Graham    schedule 20.02.2020
comment
один документ для печати. которые включают 2 шаблона, у которых есть свой layout.xsl, я получил предыдущую ошибку.   -  person Mariam A. Moustafa    schedule 20.02.2020


Ответы (1)


Чтобы решить проблему fo:table, вам нужен fo:flow внутри вашего fo:page-sequence (см. https://www.w3.org/TR/xsl11/#fo_page-sequence). У templateOne это есть (но свойства fo:block внутри fo:flow могут быть помещены в fo:flow, а fo:block могут быть опущены). templateTwo не имеет fo:flow внутри fo:page-sequence.

Другая ваша проблема заключается в том, что оба шаблона создают файл fo:root. fo:root, как следует из названия, является корнем документа FO. Поскольку документ FO, который вы создаете, также является XML-документом, документ может иметь только один элемент «document», т. е. один fo:root.

См. эту диаграмму из Раздела 6.4.1.6, Структура дерева страниц, Рекомендации XSL 1.1 (https://www.w3.org/TR/xsl11/#d0e7181)

Диаграмма структуры дерева страниц с https://www.w3.org/TR/xsl11/#d0e7181

Однако на диаграмме не видно, что fo:root может содержать несколько fo:page-sequence (см. https://www.w3.org/TR/xsl11/#fo_root).

Чтобы заставить templateOne и templateTwo работать вместе, вы должны сгенерировать один fo:root и один fo:layout-master-set, а templateOne и templateTwo генерировать контент, начиная с уровня fo:page-sequence. Что-то типа:

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

Если вы все это сделаете, то вы решите вопрос в заголовке. Значение по умолчанию для свойства initial-page-number (см. https://www.w3.org/TR/xsl11/#initial-page-number) на каждом fo:page-sequence заставит второй fo:page-sequence начинаться с номера страницы после последнего номера страницы предыдущего fo:page-sequence.

Еще одна скрытая проблема заключается в том, что и templateOne, и templateTwo включают в себя:

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

Если вы обрабатываете один исходный документ, вы получите две копии своего контента. Мы не сможем вам в этом помочь, если не будем знать больше о структуре XML, который вы пытаетесь обработать.

person Tony Graham    schedule 20.02.2020
comment
Большое спасибо за всю информацию, касающуюся того, чтобы вторая fo:page-sequence начиналась с номера страницы после номера последней страницы предыдущей fo:page-sequence. номер страницы templateOne неизвестен и генерируется динамически. поэтому номер страницы templateTwo должен начинаться с templateOne.page number+1. как я могу выполнить это требование. - person Mariam A. Moustafa; 20.02.2020
comment
Форматтер сделает это за вас. Средство форматирования создает страницы, поэтому ему, очевидно, известен номер последней страницы, которую он создал. Поведение по умолчанию — просто продолжить нумерацию страниц с предыдущей fo:page-sequence. Это свело бы нас всех с ума, если бы это не сработало таким образом. - person Tony Graham; 20.02.2020
comment
поэтому fo:page-sequence в TempolateTwo/layout может быть ‹fo:page-sequence master-reference=default-pages initial-page-number=1 format=1› или мне следует изменить значение initial-page-number? - person Mariam A. Moustafa; 20.02.2020
comment
Если вы удалите initial-page-number, у него будет начальное значение auto, которое вам нужно. Вы можете удалить format="1", так как начальное значение format равно 1. - person Tony Graham; 20.02.2020