Via xsl:for-each-group I group my data with a property pagemaster. For this group I assign the page-sequence in the attribute pagemaster. Then the template is called for each element in this group.
Now to my question: is it somehow possible that I leave the current page-sequence in the for-each loop to insert another page-sequence and then continue with the previous one?
As an example, let's assume that all elements in the group should be rendered on blue pages, but if an element has a certain attribute, a red page will be inserted at this place.
My code section looks like this:
.
<!-- master-set defined here -->
.
</fo:layout-master-set>
<xsl:for-each-group select=".//reportelements/*[pagemaster != '']" group-adjacent="pagemaster">
<fo:page-sequence master-reference="{current-grouping-key()}">
<!-- Static-Content per pagemaster Group -->
<xsl:call-template name="STATIC-CONTENT">
<xsl:with-param name="pageMaster" select="current-grouping-key()" />
</xsl:call-template>
<fo:flow flow-name="xsl-region-body">
<xsl:for-each select="current-group()">
<!-- Here, for example, i would like to check if the current element (.)
is from type "section" and the attribute "hastoc" is true.
If yes the current page sequence should be interrupted and a new page-sequence
should be inserted on which the table of contents is rendered. -->
<xsl:apply-templates select="."/>
</xsl:for-each>
</fo:flow>
</fo:page-sequence>
</xsl:for-each-group>
</fo:root>
</xsl:template>
<xsl:template name="STATIC-CONTENT">
<xsl:param name="pageMaster" />
<xsl:if test="$pageMaster = 'TITLEPAGE'">
<fo:static-content flow-name="xsl-region-after">
<fo:block text-align="right">
<fo:external-graphic src="url(file:C\Logo.pdf)" content-width="6cm" />
</fo:block>
</fo:static-content>
</xsl:if>
</xsl:template>
Xml Code looks like
<?xml version="1.0" encoding="utf-8"?>
<root>
<report>
<layout>report.xsl</layout>
<namecontent>Report</namecontent>
<reportelements>
<section>
<layout>section_normal</layout>
<pagemaster></pagemaster>
<titlecontent>Vorspann</titlecontent>
<hastoc>false</hastoc>
<reportelements>
<picture>
<layout>picture_title</layout>
<pagemaster>TITLEPAGE</pagemaster>
<titlecontent>Titelpicture</titlecontent>
<reportelements />
<path>files\Titelpicture213124.Jpeg</path>
</picture>
<section>
<layout>section_leader.xsl</layout>
<pagemaster>DIN-A4-HEADER-ODD-EVEN</pagemaster>
<titlecontent>Profil</titlecontent>
<hastoc>true</hastoc>
<reportelements>
<paragraph>
<layout>paragraph_leader.xsl</layout>
<pagemaster>DIN-A4-HEADER-ODD-EVEN</pagemaster>
<titlecontent>p1</titlecontent>
<reportelements />
<textcontent>paragraph_leader 1 text</textcontent>
</paragraph>
<paragraph>
<layout>paragraph_leader.xsl</layout>
<pagemaster>DIN-A4-HEADER-ODD-EVEN</pagemaster>
<titlecontent>p2</titlecontent>
<reportelements />
<textcontent>paragraph_leader 2 text</textcontent>
</paragraph>
.
.
.
.
I am using the Apache Formatting Object Processor 2.3
I have created index page using XSLT code. The contents name are shown to index page correctly but i want to map contents according to page number for specific title.
I am getting title with their description So I have named that block as id="TOC" and given as ref-id=”TOC” but the page number is not reflecting in my title.
Title:- Title names present in Index page.
Summary:- Title content associated with page.
The below is my XSLT-2.0 sample code:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="content_name">
<fo:block space-after="7pt" space-after.conditionality="retain" line-height="1.147" font-family="Calibri" font-size="15pt" font-weight="bold" language="FR">
<fo:inline>
<fo:leader leader-length="0pt" />
<xsl:value-of select="title"/>
<fo:page-number-citation ref-id="TOC"/>
</fo:inline>
</fo:block>
</xsl:template>
<xsl:template match="pro_list">
<fo:block space-after="15pt" space-after.conditionality="retain" line-height="1.147" font-family="Calibri" font-size="15pt" font-weight="bold" text-decoration="underline" language="FR">
<fo:inline>
<fo:leader leader-length="0pt" />
<xsl:value-of select="title" id="TOC"/>
</fo:inline>
</fo:block>
<fo:block space-after="8pt" space-after.conditionality="retain" line-height="1.147" font-family="Calibri" font-size="15pt" language="FR">
<fo:inline>
<fo:leader leader-length="0pt"/>
<xsl:value-of select="summary" disable-output-escaping="yes" />
</fo:inline>
</fo:block>
</xsl:template>
</xsl:stylesheet>
This is the output:
Contents
Title1 page no.
Title2 page no.
Title3 page no.
Suppose title1 content is associated with page2 & similar for title2-3 & title3-4, then output looks like as follows
Contents
Title1 2
Tilte2 3
Title3 4
Is there any syntax or predefined function available to do index mapping?
how can I put a fo:block with a text like:
<fo:block text-align="right" font-size="48pt">
HALLO
</fo:block>
side by side / next to a my fo:table in the xsl file.
My XSL File looks so:
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:java="http://xml.apache.org/xslt/java" xmlns:date="java.util.Date" xmlns:sf="java.text.SimpleDateFormat"
exclude-result-prefixes="java" version="1.0">
....
....
...
<xsl:template match="Order">
<fo:table border="0.5pt solid">
<fo:table-column column-width="5cm"/>
<fo:table-body>
<fo:table-row>
<fo:table-cell>
<fo:block font-size="10pt">
delivery:
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block font-weight="bold" font-size="12pt">
<xsl:value-of select="#DeliveryTime"/>
</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
</xsl:stylesheet>
Next to the table above in my xsl sheet I want to put the HALLO text.
If you really want this, you can specify a block-container that contains two block-containers with absolute positions placed side by side. The table goes in one, the text goes in the other.
But it's probably simpler to extend the table across the full page width and place the 'Hallo' text inside a cell, and span/merge cells if you need more room.
I am working on a project in which we have charts and a table exported to PDF. We are using Apache FOP for the PDF generation. The charts are in SVG and display fine if there's only one. However, we will have cases in which there are up to four, and in these instances only three of the four are fitting on the generated PDF. I need all images to fit regardless of number. I'm afraid simply putting the page in landscape will be a temporary solution for when we need even more to fit. The sizes of each chart are set in pixels from the svg generated in the client by the Highcharts library. It appears as though the images are inserted into the pdf without any scaling, even though I set attributes for the instream-foreign-object per an example seen here: Scaling images using scale-to-fit
So I need each chart to "shrink to fit". I have tried setting the length and width of the element that encloses each element that contains an instream-foreign object (I am also including my xsl). Within the instream-foreign -object I am assigning the svg width & height to the values from the actual chart svg. I thought maybe this was the problem, but if I don't include these dimensions the charts don't appear in the pdf. I also tried setting the scaling attribute to "non-uniform" per the question here: Scale images with fixed height and the results were no better. It actually stretched a chart across the whole page thus displaying only one of four. Here's my xsl:
<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>
<fo:layout-master-set>
<fo:simple-page-master master-name="exportPage">
<fo:region-body />
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="exportPage">
<fo:flow flow-name="xsl-region-body">
<fo:block id="mainTitleBlock" font-family="arial, helvetica, sans-serif" color="#5c068c" font-weight="bold">
<xsl:value-of select="exports/export/charts/#mainTitle"/>
</fo:block>
<fo:block id="timestampBlock" font-family="arial, helvetica, sans-serif" font-size="small" color="#6D869F">
<xsl:value-of select="exports/export/charts/#timeStamp"/>
</fo:block>
<!-- This is where the charts go -->
<!-- Within this block will be an inline element for each chart-->
<fo:block id="chartBlock" width="8.25in" height="6in">
<xsl:apply-templates select="exports/export/charts/chart"/>
</fo:block>
<fo:block id="tableBlock" >
<xsl:apply-templates select="exports/export/table"/>
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
<!-- Creates the table -->
<xsl:template match="table">
<fo:table table-layout="fixed" width="100%" >
<fo:table-header>
<fo:table-row>
<xsl:apply-templates select="tblRow[position() = 1]"/>
</fo:table-row>
</fo:table-header>
<fo:table-body>
<xsl:apply-templates select="tblRow[position() > 1]"/>
</fo:table-body>
</fo:table>
</xsl:template>
<xsl:template match="hdrCell">
<fo:table-cell background-color="#666" border-right-style="solid" border-right-width="1px" border-right-color="white" empty-cells="show">
<fo:block color="white" font-family="arial, helvetica, sans-serif" font-size="x-small"><xsl:value-of select="."/></fo:block>
</fo:table-cell>
</xsl:template>
<xsl:template match="tblCell">
<fo:table-cell border-bottom-style="solid" border-bottom-width="1px" border-bottom-color="#E3E3E3" >
<fo:block color="#7E7E7E" font-family="arial, helvetica, sans-serif" font-size="x-small"><xsl:value-of select="."/></fo:block>
</fo:table-cell>
</xsl:template >
<xsl:template match="tblRow[position() > 1]">
<fo:table-row>
<xsl:apply-templates />
</fo:table-row>
</xsl:template>
<xsl:template match="chart">
<fo:inline>
<fo:instream-foreign-object xmlns:svg="http://www.w3.org/2000/svg" content-width="scale-to-fit" content-height="100%" width="100%" scaling="uniform">
<svg:svg width="{svg:svg/#width}" height="{svg:svg/#height}">
<xsl:copy-of select="svg:svg"/>
</svg:svg>
</fo:instream-foreign-object>
</fo:inline>
</xsl:template>
</xsl:stylesheet>
What am I missing? Would it help to display the charts in table-cells (thus breaking the convention of not using tables for layout- the horror!)? How can I get these to scale and fit in the page?
Thanks,
Brandt
The scale property makes the chart fit in the containing block. If you haven't set dimensions for that block, the formatting engine won't know what size to scale to so it will use 100%.
I don't know what happens when you place more than one chart into one block.
You may need to put the charts in a table, one chart per column so you can set the column widths depending on the number of charts.
I have report that I must convert to PDF using xsl-fo from xml data coming from a MySQL database.
The xml structure that I am working on has already been used to create a HTML report.
There are certain fields that already have html tags inside that I was able to use in the HTML report by adding disable-output-escaping="yes" to my xsl:value-of's statement.
How do I do the similar operation in xsl-fo? Is there a way I can change the tags to be fo:inline? Or perhaps something I can change in the database output that will be the equivalent PDF version of bolding?
Here is a xml snippet:
<foal_line>
<yob>0</yob>
<description>Tis The Alarm. Unplaced at 3 in NA. Dam of <B>SA MOKEN</B> (f, by Smoke Glacken. 2 wins at 2, $60,382 in NA. Won Ken Kendrick Memorial Futurity (SRP, $25,043). 2nd Kachina S. (RUI, $10,982). 3rd Ruidoso Thoroughbred Futurity (RUI, $7,787), etc.) Granddam of <B>Dream Kin</B> (f, by Desert God. 4 wins, 2 to 4, $127,880 in US. 2nd New Mexico Cup Juv. Fillies S.-R (ZIA, $33,440). 3rd C. O. "Ken" Kendrick Memorial S-R (SRP, $7,500), Lincoln H. [R] (RUI, $5,000), Carlos Salazar S. [N] (ALB, $4,000), etc.)</description>
</foal_line>
My previous xslt snippet to create xhtml:
<tr>
<td width="30px" style="vertical-align:text-top;">
<xsl:value-of select="yob"/>
</td>
<td style="vertical-align:text-top;text-align:left;padding-left:2px">
<xsl:value-of select="description" disable-output-escaping="yes" />
</td>
</tr>
My current xsl-fo snippet:
<fo:table-row>
<fo:table-cell>
<fo:block><xsl:value-of select="yob"/></fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block><xsl:value-of select="description"/></fo:block>
</fo:table-cell>
</fo:table-row>
Edit:
Here is what I'm really getting from the server. That's what I get for using IE to view my xml.
<foal_line>
<yob>0</yob>
<description>Tis The Alarm. Unplaced at 3 in NA. Dam of <B>SA MOKEN</B> (f, by Smoke Glacken. 2 wins at 2, $60,382 in NA. Won Ken Kendrick Memorial Futurity (SRP, $25,043). 2nd Kachina S. (RUI, $10,982). 3rd Ruidoso Thoroughbred Futurity (RUI, $7,787), etc.) Granddam of <B>Dream Kin</B> (f, by Desert God. 4 wins, 2 to 4, $127,880 in US. 2nd New Mexico Cup Juv. Fillies S.-R (ZIA, $33,440). 3rd C. O. "Ken" Kendrick Memorial S-R (SRP, $7,500), Lincoln H. [R] (RUI, $5,000), Carlos Salazar S. [N] (ALB, $4,000), etc.)</description>
</foal_line>
This is why suggested answer is not working.
Instead of doing xsl:value-of for <description>, do xsl:apply-templates. You can then create a template to match <B>. In the B template you can use fo:inline to make the text bold.
Here's an example:
<xsl:template match="foal_line">
<fo:table-row>
<fo:table-cell>
<fo:block><xsl:value-of select="yob"/></fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block><xsl:apply-templates select="description"/></fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:template>
<xsl:template match="description">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="B">
<fo:inline font-weight="bold"><xsl:apply-templates/></fo:inline>
</xsl:template>
Using your XML input and the above templates, the following output is generated:
<fo:table-row xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:table-cell>
<fo:block>0</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>Tis The Alarm. Unplaced at 3 in NA. Dam of <fo:inline font-weight="bold">SA MOKEN</fo:inline> (f, by Smoke Glacken. 2 wins at 2, $60,382 in NA. Won Ken Kendrick Memorial Futurity (SRP, $25,043). 2nd Kachina S. (RUI, $10,982). 3rd Ruidoso Thoroughbred Futurity (RUI, $7,787), etc.) Granddam of <fo:inline font-weight="bold">Dream Kin</fo:inline> (f, by Desert God. 4 wins, 2 to 4, $127,880 in US. 2nd New Mexico Cup Juv. Fillies S.-R (ZIA, $33,440). 3rd C. O. "Ken" Kendrick Memorial S-R (SRP, $7,500), Lincoln H. [R] (RUI, $5,000), Carlos Salazar S. [N] (ALB, $4,000), etc.)</fo:block>
</fo:table-cell>
</fo:table-row>
Also, you should do the same for <yob> if it is also mixed content (text and other elements such as <B>).
You can also do this for your XHTML XSLT so you don't have to use disable-output-escaping (which I try to avoid at all costs).
I know that this question is rather old. I'm using Apache FOP and got stuck with this behavior of encoded or raw HTML treatment. Here's my solution I've been working on for a couple of hours.
XML:
<foal_line>
<yob>0</yob>
<description><html xmlns="http://www.w3.org/1999/xhtml">HTML text can be <b>bold</b> and <i>italic</i></html></description>
</foal_line>
XSL:
<xsl:stylesheet version="1.0" xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
>
<!-- Output in XML -->
<xsl:output method="xml" version="1.0" indent="yes" />
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<!-- Templates -->
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<xsl:template match="/">
<fo:root>
<fo:layout-master-set>
<fo:simple-page-master master-name="seite" page-width="210mm" page-height="297mm" margin="20mm 20mm 20mm 20mm">
<fo:region-body margin="20mm 0mm 10mm 0mm"/>
<fo:region-before region-name="header"/>
<fo:region-after region-name="footer"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence id="seite" master-reference="seite">
<fo:static-content flow-name="footer">
<fo:block>Footer</fo:block>
</fo:static-content>
<fo:static-content flow-name="header">
<fo:block>Header</fo:block>
</fo:static-content>
<fo:flow flow-name="xsl-region-body">
<xsl:apply-templates/>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
<xsl:template match="foal_line">
<fo:block-container>
<fo:block>Yob: <xsl:value-of select="yob"/></fo:block>
<fo:block>Desc:
<xsl:apply-templates select="description/xhtml:html"/>
</fo:block>
</fo:block-container>
</xsl:template>
<xsl:template match="description">
<xsl:message>Description</xsl:message>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="xhtml:b">
<xsl:message>Bold</xsl:message>
<fo:inline font-weight="bold"><xsl:apply-templates/></fo:inline>
</xsl:template>
<xsl:template match="xhtml:i">
<xsl:message>italic</xsl:message>
<fo:inline font-style="italic"><xsl:apply-templates/></fo:inline>
</xsl:template>
</xsl:stylesheet>
Finally I got a well-formed FO and could translate that into PDF.