Aligning an element to the right using XSL-FO, Apache FOP - xslt

I'm using XSL-FO with Apache FOP to take a sexy looking XML file and output it as a PDF, however I'm having a really basic problem trying to get a particular bit of information (the address) to be positioned from the right of the page, I can force it over to the right by increasing the left attribute, but if I change my page size, orientation or margins this will immediately be useless.
Below is the code for the XSL, note the comment on line 23.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" version="1.0">
<xsl:template match="/">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="all-pages"
page-height="297mm"
page-width="210mm"
margin-top="1cm"
margin-bottom="1cm"
margin-left="1cm"
margin-right="1cm" >
<fo:region-body margin-top="5cm" margin-bottom="1.1cm"/>
<fo:region-before extent="1cm"/>
<fo:region-after extent="5mm"/>
</fo:simple-page-master>
<fo:page-sequence-master master-name="default-sequence">
<fo:repeatable-page-master-reference master-reference="all-pages"/>
</fo:page-sequence-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="default-sequence">
<fo:static-content flow-name="xsl-region-before" font-size="10pt" font-family="Helvetica" >
<!-- HERE'S MY PROBLEM, THE RIGHT ATTRIBUTE ISN'T BEHAVING ITSELF -->
<fo:block-container absolute-position="absolute" right="4cm" top="1cm" width="6cm" border-style="solid" border-width="1mm" >
<fo:list-block >
<fo:list-item>
<fo:list-item-label>
<fo:block></fo:block>
</fo:list-item-label>
<fo:list-item-body>
<fo:block>ABC</fo:block>
</fo:list-item-body>
</fo:list-item>
<fo:list-item>
<fo:list-item-label>
<fo:block></fo:block>
</fo:list-item-label>
<fo:list-item-body>
<fo:block>123</fo:block>
</fo:list-item-body>
</fo:list-item>
</fo:list-block>
</fo:block-container>
</fo:static-content>
<fo:static-content flow-name="xsl-region-after" padding-top="2pt" border-top-style="solid" border-top-width="1pt" border-top-color="rgb(192,192,192)" font-size="10pt" font-family="Helvetica">
<fo:block></fo:block>
</fo:static-content>
<fo:flow flow-name="xsl-region-body" font-size="10pt" font-family="Helvetica">
<fo:block></fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
</xsl:stylesheet>
And as you can see by this screenshot the element isn't positioning correctly:
Any one know know why this is happening?

Bugger, looked at the FOP changelog and the two years between versions 0.95 and 1.0 made me think whether it was a bug, downloaded the new binaries and it's now positioning my element from the right.

Related

How to create border in A4 page and fo:block rounded corner in using - XSL-FO

How to create a border in the A4 page and How to make rounded fo:block.
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:fox="http://xmlgraphics.apache.org/fop/extensions">
<fo:layout-master-set>
<fo:simple-page-master master-name="A4" page-height="11.40in" page-width="8.27in" margin-top="0.30in" margin-bottom=".030in" margin-left="0.30in" margin-right="0.30in">
<fo:region-body region-name="body" margin=".30in"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="A4">
<fo:flow flow-name="body">
<fo:block text-align="center" border="1pt" border-style="solid">
How to create rounded border
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
I have tested following XSL-FO file via FOP 2.5.
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:fox="http://xmlgraphics.apache.org/fop/extensions">
<fo:layout-master-set>
<fo:simple-page-master master-name="A4" page-height="11.40in" page-width="8.27in" margin-top="0.30in" margin-bottom=".030in" margin-left="0.30in" margin-right="0.30in">
<fo:region-body region-name="body" margin=".30in"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="A4">
<fo:flow flow-name="body">
<fo:block text-align="center" border="1pt" border-style="solid" fox:border-radius="10pt 15pt">
Hello Word!
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
[The output snapshot]
[Sample command-line]
[Oxygen Transformation Scenario]
[Oxygen 21.1 with FOP 2.3 build result]
fo:region-body can have border properties. See https://www.w3.org/TR/xsl11/#fo_region-body.
Rounded corners are not in the XSL 1.1 Recommendation. However, your XSL formatter probably has an extension for rounded corners:
Antenna House has axf:border-radius and related properties (see https://www.antenna.co.jp/AHF/help/v70e/ahf-ext.html#axf.border-radius).
FOP has fox:border-*-*-radius properties (see https://xmlgraphics.apache.org/fop/2.5/extensions.html#rounded-corners).

FOP first page without page number

I have the xsl-fo template:
<xsl:template match="/">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master margin-right="1cm"
margin-left="2.7cm" margin-bottom="2cm" margin-top="2cm"
page-width="21.5cm" page-height="29.7cm" master-name="first">
<fo:region-body margin-right="1cm" margin-left="0cm" />
<fo:region-after region-name="xsl-region-after" display-align="before" extent="0.7in"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="first">
<fo:static-content flow-name="xsl-region-after">
<fo:block text-align="center" font-size="10pt">
<fo:page-number />
</fo:block>
</fo:static-content>
<fo:flow flow-name="xsl-region-body">
<xsl:apply-templates select="rootElement" />
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
All works excellent, but first page have a page number.
I do not need number on first page.
Thanks y'all!
You have to create a separate page-sequence-master for the first page, that does not include the page number. Then use a statement like this to specify which master will be used for each page of the book:
<fo:page-sequence-master master-name="chapter">
<fo:repeatable-page-master-alternatives>
<fo:conditional-page-master-reference master-reference="page_first" page-position="first"/>
<fo:conditional-page-master-reference master-reference="page_even" odd-or-even="even"/>
<fo:conditional-page-master-reference master-reference="page_odd" odd-or-even="odd"/>
</fo:repeatable-page-master-alternatives>
</fo:page-sequence-master>
(copied from one of my projects, so you'll have to adapt it to your structure)

How to show correctly tabulation in xsl-fo?

I have an XML document and I am creating an XSL-FO file to convert it to pdf with apache-fop.
In the xml, there are sections <code> to show... code.
In the xsl-fo, I added the white-space="pre" sentence to preserve the code format, but tabulations are shown like single space:
XML section:
<code><![CDATA[
function callback( widget )
{
var ui = widget; // It should be a tab
}
]]></code>
XSL-FO section:
<xsl:template match="code">
<fo:block font-size="10pt" font-family="monospace" white-space="pre" color="#008000" background-color="#f8f8f8">
<xsl:apply-templates/>
</fo:block>
</xsl:template>
Resulting PDF:
function callback( widget )
{
var ui = widget; // It should be a tab
}
So my question is: How to preserve or set the size of the tabulation?
Edited: I am using apache-fop 1.1
A full example:
proyecto.xml (do not forget to replace the 4 spaces by a tab before "var ui...")
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="proyecto.xsl"?>
<document>
<code><![CDATA[
function callback( widget )
{
var ui = widget; // It should be a tab
}
]]></code>
</document>
proyecto.xsl
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:template match ="document">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="OnePage" margin="1in"
page-height="29.7cm"
page-width="21cm"
margin-top="2.5cm"
margin-bottom="2.5cm"
margin-left="3.5cm"
margin-right="2.5cm">
<fo:region-body margin="0cm"/>
</fo:simple-page-master>
<fo:page-sequence-master master-name="Page">
<fo:single-page-master-reference master-reference="OnePage"/>
</fo:page-sequence-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="Page">
<fo:flow flow-name="xsl-region-body">
<xsl:apply-templates/>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
<xsl:template match="code">
<fo:block font-size="10pt" font-family="monospace" white-space="pre">
<xsl:apply-templates/>
<!--<xsl:value-of select="replace( . , 'a', 'b')"/>-->
</fo:block>
</xsl:template>
</xsl:stylesheet>
PDF result (screen):
Replace the tabs by four spaces, as suggested by #mzjn already in the comments.
XML Input
<code><![CDATA[
function callback( widget )
{
var ui = widget; // It should be a tab
}
]]></code>
XSLT Stylesheet
<?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="A4-portrait"
page-height="29.7cm" page-width="21.0cm" margin="2cm">
<fo:region-body/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="A4-portrait">
<fo:flow flow-name="xsl-region-body">
<fo:block font-size="10pt" font-family="monospace" linefeed-treatment="preserve" white-space-collapse="false" white-space-treatment="preserve" wrap-option="no-wrap" color="#008000" background-color="#f8f8f8">
<xsl:value-of select="replace(code,' ',' ')"/>
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
</xsl:stylesheet>
Now, after replacing the tab characters with whitespaces, the output is rendered correctly by FOP.
There is no obvious flaw with outputting tabs, but bear in mind that Apache FOP is only partially compliant in regard to the whitespace-treatment property: http://xmlgraphics.apache.org/fop/compliance.html , even if it says that only fo:inline elements are affected of this.

How to use `xsl:include` with apache fop

I use apache FOP to generate pdf files. I have this xsl code
<xsl:stylesheet version="1.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 font-size="11pt" font-family="serif">
<fo:layout-master-set>
<fo:simple-page-master master-name="A4-portrait"
page-height="29.7cm" page-width="21.0cm" margin-top="1cm"
margin-left="1.5cm" margin-right="1cm" margin-bottom="1cm">
<fo:region-body />
<fo:region-after region-name="footer" extent="15mm"/>
</fo:simple-page-master>
<fo:simple-page-master master-name="A4-landscape"
page-width="29.7cm" page-height="21.0cm" margin-top="1cm"
margin-left="1cm" margin-right="1cm" margin-bottom="1cm">
<fo:region-body />
<fo:region-after region-name="footer2" display-align="after" extent="0cm"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="A4-portrait">
<xsl:include href="footer_common.xsl"/>
<fo:flow flow-name="xsl-region-body">
....
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
</xsl:stylesheet>
Notice the element <xsl:include href="footer_common.xsl"/>
The inclusion does not work!
And here is footer_common.xsl:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format"
version="1.0">
<fo:static-content flow-name="footer" font-size="7pt">
<fo:table>
<fo:table-column column-width="70mm"/>
<fo:table-column column-width="70mm"/>
<fo:table-column column-width="70mm"/>
<fo:table-body>
...........
</fo:table-body>
</fo:table>
</fo:static-content>
</xsl:stylesheet>
Both .xsl files are in the same resource directory. If it matters - I use eclipse for development. In my java code I get the main .xsl file as a resource stream and use it for the transformation.
The error message is
xsl:include ist an dieser Position in der Formatvorlage nicht zulässig!
which means, xsl:include is not allowed at that position in the template
Can anyone see what I am doing wrong?
Thanks for any help or hints.
xsl:include is a top-level element (actually, a stylesheet declaration), which means that it may only appear as an immediate child of xsl:stylesheet. So, you simply cannot include a stylesheet from within an fo:page-sequence element.
But I think you're not in need of xsl:include and a separate stylesheet, but of xsl:call-template and a separate named template.
Write a separate template similar to the following:
<xsl:template name="footer-ebase">
<fo:static-content flow-name="footer" font-size="7pt">
<fo:table>
<fo:table-column column-width="70mm"/>
<fo:table-column column-width="70mm"/>
<fo:table-column column-width="70mm"/>
<fo:table-body>
<!--...-->
</fo:table-body>
</fo:table>
</fo:static-content>
</xsl:template>
In the main template (the place where you'd like to insert content), reference the named template with:
<fo:page-sequence master-reference="A4-portrait">
<xsl:call-template name="footer-ebase"/>
<fo:flow flow-name="xsl-region-body">
<!--...-->
</fo:flow>
</fo:page-sequence>
Note that it does not always make sense to write named templates. It is advisable if
your code would otherwise be redundant because you need the same functionality in several places
the code would clutter the template and make it hard to read
you use recursion to solve a problem
If you want to split content into separate templates for no apparent reason, then you'd best do away with it alltogether.
You can still put the named template into a separate stylesheet if you wish, but then you need to use xsl:include as a top-level element:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:include href="footer-ebase.xsl"/>
<!--...-->
</xsl:stylesheet>

XSL: Filtered for-each in Two Columns

I am using a program to generate a report. The program uses an XSL file to generate a PDF report. I am trying to create a custom XSL file.
In my example, I am trying to only generate a report for items that are 3.5" Floppy OR 5.25" Floppy (separately). In addition to this, I am trying to fit the results in two column per index card - for printing.
I'm not an XSL expert, but I've done a research, and found several possible solutions for what I'm trying to achieve (mainly this question) however the final results are always not what I want them to be - I may have a wrong concept of XSL parts, and I'd appreciate any input/pointers.
Here is a part from the XML:
?xml version="1.0" encoding="UTF-8" ?>
<catalog-objects xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="temp.xsd">
<software-item>
<item>Software</item>
<media-types>
<storage-medium>
<name>5.25" Floppy</name>
</storage-medium>
</media-types>
<title>Title 1</title>
</software-item>
<software-item>
<item>Software</item>
<media-types>
<storage-medium>
<name>3.5" Floppy</name>
</storage-medium>
</media-types>
<title>Title 2</title>
</software-item>
<software-item>
<item>Software</item>
<media-types>
<storage-medium>
<name>3.5" Floppy</name>
</storage-medium>
<storage-medium>
<name>5.25" Floppy</name>
</storage-medium>
</media-types>
<title>Title 3</title>
</software-item>
<software-item>
<item>Software</item>
<media-types>
<storage-medium>
<name>CD-Rom</name>
</storage-medium>
</media-types>
<title>Title 4</title>
</software-item>
Here is a part from the XSL I created:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.1"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format"
exclude-result-prefixes="fo">
<xsl:import href="../../_stylesheets/pdf_desert.xsl" />
<xsl:output method="xml" version="1.0" omit-xml-declaration="no" indent="yes" />
<xsl:param name="versionParam" select="'1.0'" />
<xsl:template match="/">
<xsl:param name="size" select="count(catalog-objects/software-item)"/>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="Index Card 4X6"
page-height="4in" page-width="6in" margin-top="4mm"
margin-bottom=".65in" margin-left="4mm" margin-right="4mm">
<fo:region-body />
<fo:region-after />
</fo:simple-page-master>
</fo:layout-master-set>
<xsl:variable name="individualFloppies" select="catalog-objects/software-item[(contains(media-types, '5.25') and not(contains(media-types, '3.5') or contains(media-types, 'ROM') or contains(media-types, 'Disc') or contains(media-types, 'CD') or contains(media-types, 'DVD') or contains(media-types, 'ray'))) or (contains(media-types, '3.5') and not(contains(media-types, '5.25') or contains(media-types, 'ROM') or contains(media-types, 'Disc') or contains(media-types, 'CD') or contains(media-types, 'DVD') or contains(media-types, 'ray')))]" />
<xsl:param name="size" select="$individualFloppies"/>
<xsl:for-each select="$individualFloppies[ceiling($size div 2) >= position()]">
<fo:page-sequence master-reference="Index Card 4X6">
<fo:static-content flow-name="xsl-region-after">
<fo:block font-size="{$fontSize}">
</fo:block>
</fo:static-content>
<fo:flow flow-name="xsl-region-body">
<fo:block font-size="{$fontSize}">
<fo:table table-layout="fixed" width="100%" border-collapse="collapse">
<fo:table-column column-width="45%" />
<fo:table-column column-width="45%" />
<fo:table-body>
<fo:table-row>
<fo:table-cell>
<fo:block text-align="right" font-size="8"><fo:inline font-weight="bold">ID </fo:inline><xsl:value-of select='format-number(archive-id, "000000")' /></fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block text-align="right" font-size="8"><fo:inline font-weight="bold">ID </fo:inline><xsl:value-of select='format-number(following::software-item[ceiling($size div 2)]/archive-id, "000000")' /></fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell border-bottom="1px solid #000000">
<fo:block text-align="center" padding-top="0.2in" font-size="12" font-weight="bold">
<xsl:value-of select="title" />
</fo:block>
</fo:table-cell>
<fo:table-cell border-bottom="1px solid #000000">
<fo:block text-align="center" padding-top="0.2in" font-size="12" font-weight="bold">
<xsl:value-of select="following::software-item[ceiling($size div 2)]/title" />
</fo:block>
</fo:table-cell>
</fo:table-row>
The PDF report that is generated by the program is wrong because I also get cells with titles that do not match the filter. Also, sometimes at least one item title is not shown.
I tried "reverse engineering" to check whether my variable ($individualFloppies) filter isn't right, but when not using the two column approach I get good results however each in its own row.
It feels as if the following:: is causing the problem but it's just a guess.
I also tried following-sibling::, position() mod 2 = 1 as well as minimizing the filter I have.
If anyone can shed some light and tell me how far I am to what I am trying to achieve and where I am wrong I'd appreciate it very much.
As a first time poster here, I hope I provided all the important information.
EDIT:
I wasn't sure how to attach here the PDF files of the desired and the current output so I'll just ASCII it:
From the XML above, the desired output should only be one page:
╔════════════╤════════════╗
║ Title 1 │ Title 2 ║
╠════════════╪════════════╣
║ │ ║
║ │ ║
║ │ ║
╚════════════╧════════════╝
What I get after generating the report are two pages:
PAGE 1:
╔════════════╤════════════╗
║ Title 1 │ Title 3 ║
╠════════════╪════════════╣
║ │ ║
║ │ ║
║ │ ║
╚════════════╧════════════╝
PAGE 2:
╔════════════╤════════════╗
║ Title 2 │ Title 4 ║
╠════════════╪════════════╣
║ │ ║
║ │ ║
║ │ ║
╚════════════╧════════════╝
To put the logic in writing:
Since 'Title 1' is only '5.25" Floppy' and 'Title 2' is only '3.5" Floppy' they are the only two that should show up.
'Title 3' is '5.25" Floppy' but also is '3.5" Floppy' so it shouldn't show.
'Title 4' is a 'CD-Rom' so it shouldn't show as a column as well.
Writing this makes me realize that the filter I am using isn't working - odd considering I am using some similar filter on some different aspect and it does work.
I hope these edits are what was expected as "examples" and they clarify the issue more.
AFAICT, the problem here is with the expression:
<xsl:value-of select="following::software-item[ceiling($size div 2)]/title" />
Although you are in the context of looping over the filtered variable, the following:: axis is evaluated in the context of the source document. Here's a small stylesheet that demonstrates the problem in isolation as well as a possible solution:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:template match="/">
<xsl:variable name="individualFloppies" select="catalog-objects/software-item[(contains(media-types, '5.25') and not(contains(media-types, '3.5') or contains(media-types, 'ROM') or contains(media-types, 'Disc') or contains(media-types, 'CD') or contains(media-types, 'DVD') or contains(media-types, 'ray'))) or (contains(media-types, '3.5') and not(contains(media-types, '5.25') or contains(media-types, 'ROM') or contains(media-types, 'Disc') or contains(media-types, 'CD') or contains(media-types, 'DVD') or contains(media-types, 'ray')))]" />
<out>
<wrong>
<xsl:for-each select="$individualFloppies">
<pair>
<left><xsl:value-of select="title" /></left>
<right><xsl:value-of select="following::software-item[1]/title"/></right>
</pair>
</xsl:for-each>
</wrong>
<right>
<xsl:for-each select="$individualFloppies">
<xsl:variable name="pos" select="position()" />
<pair>
<left><xsl:value-of select="title" /></left>
<right><xsl:value-of select="$individualFloppies[$pos+1]/title"/></right>
</pair>
</xsl:for-each>
</right>
</out>
</xsl:template>
</xsl:stylesheet>
With the help of michael.hor257k (thanks again!) I managed to add and change the necessary lines of code so it'll generate the report I was aiming for.
Here is the updated code (beginning from where the first change is applied):
<xsl:variable name="individualFloppies" select="catalog-objects/software-item[normalize-space(media-types)='3.5" Floppy' or normalize-space(media-types)='5.25" Floppy']" />
<xsl:param name="size" select="$individualFloppies"/>
<xsl:for-each select="$individualFloppies">
<xsl:variable name="pos" select="position()" />
<xsl:if test="position() mod 2 = 1">
<fo:page-sequence master-reference="Index Card 4X6">
<fo:static-content flow-name="xsl-region-after">
<fo:block font-size="{$fontSize}">
</fo:block>
</fo:static-content>
<!--Table Begins-->
<fo:flow flow-name="xsl-region-body">
<fo:block font-size="{$fontSize}">
<fo:table table-layout="fixed" width="100%" border-collapse="collapse">
<fo:table-column column-width="2.5%" />
<fo:table-column column-width="45%" />
<fo:table-column column-width="2.5%" />
<fo:table-column column-width="2.5%" />
<fo:table-column column-width="45%" />
<fo:table-column column-width="2.5%" />
<fo:table-body>
<fo:table-row>
<fo:table-cell number-columns-spanned="3">
<fo:block text-align="right" font-size="8"><fo:inline font-weight="bold">ID </fo:inline><xsl:value-of select='format-number(archive-id, "000000")' /></fo:block>
</fo:table-cell>
<xsl:choose>
<xsl:when test="position() != last()">
<fo:table-cell number-columns-spanned="3">
<fo:block text-align="right" font-size="8"><fo:inline font-weight="bold">ID </fo:inline><xsl:value-of select='format-number($individualFloppies[$pos+1]/archive-id, "000000")' /></fo:block>
</fo:table-cell>
</xsl:when>
<xsl:otherwise>
<fo:table-cell number-columns-spanned="3"><fo:block></fo:block></fo:table-cell>
</xsl:otherwise>
</xsl:choose>
</fo:table-row>
<fo:table-row>
<fo:table-cell><fo:block></fo:block></fo:table-cell>
<fo:table-cell border-bottom="1px solid #000000">
<fo:block text-align="center" padding-top="0.2in" font-size="12" font-weight="bold">
<xsl:value-of select="title" />
</fo:block>
</fo:table-cell>
<fo:table-cell><fo:block></fo:block></fo:table-cell>
<fo:table-cell><fo:block></fo:block></fo:table-cell>
<xsl:choose>
<xsl:when test="position() != last()">
<fo:table-cell border-bottom="1px solid #000000">
<fo:block text-align="center" padding-top="0.2in" font-size="12" font-weight="bold">
<xsl:value-of select="$individualFloppies[$pos+1]/title" />
</fo:block>
</fo:table-cell>
</xsl:when>
<xsl:otherwise>
<fo:table-cell><fo:block></fo:block></fo:table-cell>
</xsl:otherwise>
</xsl:choose>
<fo:table-cell><fo:block></fo:block></fo:table-cell>
</fo:table-row>
Pointing out the updated lines:
Line 1: Cleaner and, I believe, better way to filter the data into the variable.
Lines 3-4: Implementing first part of michael.hor257k example
Line 5: Make the loop work only on the odd nodes (not sure my terminology is correct)
Lines 26-35/46-57: Implement the second part from michael.hor257k' example as well as check if the current position is the last one.