XSL-FO footer in static but dynamic content?

I currently have an XSL file that I use to convert XML to FO format (XSL-FO). The only problem is the footers. I have a requirement to display a text link from the footer of each page to one of the other pages. This means that I need to make the footer text dynamic. For example, here is some abstract text from each page:

page 1: Topic A page 2: Topic B page 3: Topic C, Subtopic of A page 4: Topic D, Subtopic of A page 5: Topic E, Subtopic of B 

Imagine a "subtopic" is the footer to display each page.

Consider the following XML:

 <DATA_DS> <LIST_ITEMS> <ITEMS> <isChild>0</isChild> <myvalue>abc</myvalue> <isLastChild>0</isLastChild> </ITEMS> <ITEMS> <isChild>1</isChild> <myvalue>def</myvalue> <isLastChild>0</isLastChild> </ITEMS> <ITEMS> <isChild>1</isChild> <myvalue>ghi</myvalue> <isLastChild>0</isLastChild> </ITEMS> <ITEMS> <isChild>1</isChild> <myvalue>xyz</myvalue> <isLastChild>1</isLastChild> </ITEMS> </LIST_ITEMS> </DATA_DS> 

and this XSL:

 <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format"> <xsl:output method="xml" indent="yes"/> <xsl:template match="/"> <fo:root> <fo:layout-master-set> <fo:simple-page-master master-name="parentLOBPage-master" page-width="11in" page-height="8.5in" margin-left="1.3in" margin-right="0.65in" margin-top="0.35in" margin-bottom="0.35in"> <fo:region-body region-name="body" margin-top="0.5in" margin-right="0.65in"/> <fo:region-after region-name="footer" extent="14mm" /> </fo:simple-page-master> <fo:simple-page-master master-name="childLOBPage-master" page-width="11in" page-height="8.5in" margin-left="1.3in" margin-right="0.65in" margin-top="0.35in" margin-bottom="0.35in"> <fo:region-body region-name="body" margin-top="0.5in" margin-right="0.65in"/> <fo:region-after region-name="footer" extent="14mm"/> </fo:simple-page-master> <fo:page-sequence-master master-name="parentLOBPage"> <fo:repeatable-page-master-reference master-reference="parentLOBPage-master"/> </fo:page-sequence-master> <fo:page-sequence-master master-name="childLOBPage"> <fo:repeatable-page-master-reference master-reference="childLOBPage-master"/> </fo:page-sequence-master> </fo:layout-master-set> <xsl:apply-templates/> </fo:root> </xsl:template> <xsl:template match="DATA_DS"> <xsl:for-each-group select="LIST_ITEMS/ITEMS" group-adjacent="isChild"> <xsl:choose> <xsl:when test="isChild = 0"> <fo:page-sequence master-reference="parentLOBPage"> <fo:static-content flow-name="footer"> <fo:table width="100%" table-layout="fixed" margin-top="5mm"> <fo:table-column column-width="80%"/> <fo:table-column column-width="20%"/> <fo:table-body> <fo:table-row> <fo:table-cell> <fo:block text-align="left" font-family="Arial" font-size="7pt" font-weight="normal">parent footer</fo:block> </fo:table-cell> <fo:table-cell> <fo:block text-align="right" font-family="Arial" font-size="7pt" font-weight="normal">Page <fo:page-number/> of <fo:page-number-citation ref-id="last-page" /></fo:block> </fo:table-cell> </fo:table-row> </fo:table-body> </fo:table> </fo:static-content> <fo:flow flow-name="body"> <xsl:for-each select="current-group()"> <xsl:apply-templates select="."/> </xsl:for-each> </fo:flow> </fo:page-sequence> </xsl:when> <xsl:otherwise> <fo:page-sequence master-reference="childLOBPage"> <fo:static-content flow-name="footer"> <fo:table width="100%" table-layout="fixed" margin-top="5mm"> <fo:table-column column-width="80%"/> <fo:table-column column-width="20%"/> <fo:table-body> <fo:table-row> <fo:table-cell> <fo:block text-align="left" font-family="Arial" font-size="7pt" font-weight="normal">child footer: <xsl:value-of select="myvalue"/></fo:block> </fo:table-cell> <fo:table-cell> <fo:block text-align="right" font-family="Arial" font-size="7pt" font-weight="normal">Page <fo:page-number/> of <fo:page-number-citation ref-id="last-page" /></fo:block> </fo:table-cell> </fo:table-row> </fo:table-body> </fo:table> </fo:static-content> <fo:flow flow-name="body"> <xsl:for-each select="current-group()"> <xsl:apply-templates select="."/> </xsl:for-each> <fo:block id="last-page"/> </fo:flow> </fo:page-sequence> </xsl:otherwise> </xsl:choose> </xsl:for-each-group> </xsl:template> <xsl:template match="ITEMS"> <fo:table width="100%" table-layout="fixed" margin-top="5mm"> <fo:table-column column-width="20%"/> <fo:table-column column-width="80%"/> <fo:table-body> <fo:table-row> <fo:table-cell> <fo:block text-align="left" font-family="Arial" font-size="10pt" font-weight="bold">big table</fo:block> </fo:table-cell> <fo:table-cell> <fo:block text-align="left" font-family="Arial" font-size="10pt" font-weight="bold">some stuff</fo:block> </fo:table-cell> </fo:table-row> </fo:table-body> </fo:table> <xsl:if test="isChild = 1 and isLastChild = 0"> <fo:block page-break-after="always"/> </xsl:if> </xsl:template> </xsl:stylesheet> 

Since I transfer most of the content of each page to fo: table, and some tables overflow to 2 + pages, I can’t just put “dynamic footer text” after each table because it will not be displayed on every page.

So, I suppose my use of fo: static-content is not suitable, although it does what I need to dynamically display page numbers (e.g., page x of y). The output shows that for each page of the lower lower level, the value is displayed as "def", which is the first "child" in the list. So fo: static-content populates itself the first time it starts and is not updated for subsequent pages ... so my approach is wrong. I need to be guided by how to reconsider my approach ...

Any suggestions on how I work on the way I need for my XSL-FO situation? Thanks...

+4
source share
1 answer

Your code does not have the proper structure for dynamic content in static content.

The concept you are missing is that your footer should “extract the markers” that you set at points “on the fly” in the stream. One footer for all pages extracts one marker class from the contents of the pages, and you change the marker at the points in your stream, and the search receives the last marker (or other parameters).

So, you only need one footer that has the “Page x of y” bit, and you need to include an element that retrieves the marker of a particular class. Then, in your thread, with all your themes and subtopics, and when you get to the first element of each, you define a marker with the text that you want to see in the footer.

The XSL-FO output that XSLT should receive corresponds to the lines:

  <fo:static-content> ... page x of y stuff ... <fo:retrieve-marker retrieve-class-name="topic"/> </fo:static-content> <fo:flow> <fo:table> ... <fo:table-cell> <fo:marker marker-class-name="topic">Topic A</fo:marker> ... <fo:table-cell> <fo:marker marker-class-name="topic">Topic B</fo:marker> ... <fo:table-cell> <fo:marker marker-class-name="topic">Topic C, Subtopic of A</fo:marker> ... <fo:table-cell> <fo:marker marker-class-name="topic">Topic D, Subtopic of A</fo:marker> ... <fo:table-cell> <fo:marker marker-class-name="topic">Topic E, Subtopic of B</fo:marker> 

I suggest you look at the frames called Dynamic Content in Static Content, starting on page 257 of the free preview of my Try and Buy book:

http://www.CraneSoftwrights.com/training/#pfux

There are nuances of attributes for searching and positioning markers with diagrams indicated there.

+5
source

Source: https://habr.com/ru/post/1489573/


All Articles