how to transform different tables in a XML file to PDF by using a XSL-FO stylesheet and Apache FOP
I transformed the XML-file ReportXHTML.xml with 2 tables to xhtml by using the xsl stylesheet ReportXHTML.xsl. As a next step I built the comparable XSL-FO file ReportFO.xsl to use it together with the modified xml-file ReportFO.xml and Apache FOP to get a PDF file, but my java application FopReport.java failed by this ValidationException
"fo:table-row" is missing child elements. Required content model:
(table-cell+)
Looking for a solution I read the XSL-Fo specification and modified the XSL-FO file by deleting the xsl-statement for-each in the xsl-template named table-rows. I got the PDF file ReportFO.pdf.
That shows that the xsl-statement for-each in the xsl-template named table-head works. The xsl-template named table-rows is comparable to it, but failed. That's my issue. What is to modify in my XSL-FO file? Thanks for your help.
file ReportXHTML.xml
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xml" href="ReportXHTML.xsl" ?>
<report>
<table>
<tableRow>
<tableHead>Name</tableHead>
<tableHead>Street</tableHead>
<tableHead>City</tableHead>
</tableRow>
<tableRow>
<entry>Torsten Horn</entry>
<entry>Hauptsr. 44</entry>
<entry>Aachen</entry>
</tableRow>
<tableRow>
<entry>Heinz Hinz</entry>
<entry>Bahnhofstr. 22</entry>
<entry>Hamburg</entry>
</tableRow>
<tableRow>
<entry>Karl Kunz</entry>
<entry>Königstr. 1</entry>
<entry>Köln</entry>
</tableRow>
</table>
<table>
<tableRow>
<tableHead>Name</tableHead>
<tableHead>City</tableHead>
</tableRow>
<tableRow>
<entry>Torsten Horn</entry>
<entry>Aachen</entry>
</tableRow>
<tableRow>
<entry>Heinz Hinz</entry>
<entry>Hamburg</entry>
</tableRow>
<tableRow>
<entry>Karl Kunz</entry>
<entry>Köln</entry>
</tableRow>
</table>
</report>
stylesheet ReportXHTML.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/1999/xhtml">
<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
<html>
<head>
<title>Report</title>
<meta http-equiv="content-type" content="text/html;charset=UTF-8"/>
</head>
<body>
<xsl:apply-templates/>
</body>
</html>
<xsl:template match="table">
<p>
<table border="1" cellspacing="0" cellpadding="5">
<tr>
<xsl:for-each select="tableRow/tableHead">
<th><xsl:apply-templates/></th>
</xsl:for-each>
</tr>
<xsl:for-each select="tableRow">
<tr>
<xsl:for-each select="entry">
<td><xsl:apply-templates/></td>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
</p>
</xsl:template>
</xsl:stylesheet>
result in FireFox:
image of result
stylesheet ReportFO.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xs:stylesheet version="1.0"
xmlns:xs="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<!-- XLS/ FO Specification see: https://www.w3.org/TR/xsl11/ -->
<!-- Attribute-Sets -->
<xs:attribute-set name="cell-style">
<xs:attribute name="border-width">0.5pt</xs:attribute>
<xs:attribute name="border-style">solid</xs:attribute>
</xs:attribute-set>
<xs:attribute-set name="block-style">
<xs:attribute name="font-size"> 10pt</xs:attribute>
<xs:attribute name="line-height">15pt</xs:attribute>
<xs:attribute name="start-indent">1mm</xs:attribute>
<xs:attribute name="end-indent"> 1mm</xs:attribute>
</xs:attribute-set>
<!-- Page Layout -->
<xs:template match="/">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="DIN-A4"
page-height="29.7cm" page-width="21cm"
margin-top="2cm" margin-bottom="1.5cm"
margin-left="2.5cm" margin-right="1.0cm">
<fo:region-body
margin-top="1.5cm" margin-bottom="1.0cm"
margin-left="0.0cm" margin-right="0.0cm"/>
<fo:region-before region-name="header" extent="1.3cm"/>
<fo:region-after region-name="footer" extent="1.0cm"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="DIN-A4">
<fo:static-content flow-name="header">
<fo:block font-size="14pt" font-family="Helvetica" font-weight="bold" text-align="left">
Report
</fo:block>
<fo:block text-align-last="justify"><fo:leader leader-pattern="rule" rule-thickness="0.5" />
</fo:block>
</fo:static-content>
<fo:static-content flow-name="footer">
<fo:block text-align-last="justify"><fo:leader leader-pattern="rule" rule-thickness="0.5" />
</fo:block>
<fo:block font-size="10pt" text-align="center" >
Page <fo:page-number/> of <fo:page-number-citation ref-id="LastPage"/>
</fo:block>
</fo:static-content>
<fo:flow flow-name="xsl-region-body">
<xs:apply-templates/>
<fo:block id="LastPage"/>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xs:template>
<!-- Table-Head -->
<xs:template name="table-head">
<fo:table-row>
<xs:for-each select="tableRow/tableHead">
<fo:table-cell xs:use-attribute-sets="cell-style">
<fo:block xs:use-attribute-sets="block-style" text-align="center">
<xs:apply-templates/>
</fo:block>
</fo:table-cell>
</xs:for-each>
</fo:table-row>
</xs:template>
<!-- Table-Rows -->
<xs:template name="table-rows">
<fo:table-row>
<xs:for-each select="tableRow/entry">
<fo:table-cell xs:use-attribute-sets="cell-style">
<fo:block xs:use-attribute-sets="block-style">
<xs:apply-templates/>
</fo:block>
</fo:table-cell>
</xs:for-each>
</fo:table-row>
</xs:template>
<!-- Table -->
<xs:template match="report/table">
<fo:block><fo:leader /></fo:block>
<fo:table border-style="solid" table-layout="fixed" width="100%">
<fo:table-header>
<xs:call-template name="table-head"/>
</fo:table-header>
<fo:table-body>
<xs:for-each select="tableRow">
<xs:call-template name="table-rows"/>
</xs:for-each>
</fo:table-body>
</fo:table>
</xs:template>
</xs:stylesheet>
modified xml-file ReportFO.xml
<?xml version="1.0" encoding="UTF-8"?>
<report>
<table>
<tableRow>
<tableHead>Name</tableHead>
etc .....
FopReport.java
import java.io.*;
import javax.xml.transform.*;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamSource;
import org.apache.fop.apps.*;
import org.apache.*;
// compile by: javac -classpath ".:lib/fop.jar:lib/xmlgraphics-commons-2.3.jar" FopReport.java
// run by:
// java -classpath ".:lib/fop.jar:lib/xmlgraphics-commons-2.3.jar:lib/commons-logging-1.0.4.jar:lib/avalon-framework-api-4.3.1.jar:lib/avalon-framework-impl-4.3.1.jar:lib/commons-io-1.3.1.jar:lib/batik-all-1.10.jar" FopReport ReportFO.xsl ReportFO.xml ReportFO.pdf
// see : https://xmlgraphics.apache.org/fop/2.3/embedding.html
public class FopReport
public static void main( String args ) throws Exception
if( args.length != 3 )
System.out.println( "Enter XSL- and XML-Inputfile, PDF-Outputfile." );
return;
FopReport.xmlToPdfPerXsl( args[0], args[1], args[2] );
System.out.println( args[0] + " + " + args[1] + " --> " + args[2] );
public static void xmlToPdfPerXsl( String inputXSL, String inputXML, String outputPDF ) throws Exception
// Step 1: Construct a FopFactory by specifying a reference to the configuration file
// (reuse if you plan to render multiple documents!)
FopFactory fopFactory = FopFactory.newInstance(new File("fop.xconf"));
// Step 2: Set up output stream
OutputStream pdf = new FileOutputStream( outputPDF );
// Step 3: Construct fop with desired output format
// Fop fop = FopFactory.newFop( MimeConstants.MIME_PDF, pdf );
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, pdf);
// Step 5: Setup input and output for XSLT transformation
// Setup input stream
Source xml = new StreamSource( inputXML );
Source xsl = new StreamSource( inputXSL );
// Resulting SAX events (the generated FO) must be piped through to FOP
Result sax = new SAXResult( fop.getDefaultHandler() );
// Step 4: Setup JAXP using identity transformer
// Transformer transformer = TransformerFactory.newInstance().newTransformer( xsl );
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer( xsl ); // identity transformer
// Step 6: Start XSLT transformation and FOP processing
transformer.transform( xml, sax );
Validation Exception
Nov. 11, 2018 7:34:05 NACHM. org.apache.fop.apps.FopConfParser configure
INFORMATION: Default page-height set to: 11in
Nov. 11, 2018 7:34:05 NACHM. org.apache.fop.apps.FopConfParser configure
INFORMATION: Default page-width set to: 8.26in
ERROR: '"fo:table-row" is missing child elements. Required content model: (table-cell+) (No context info available)'
Exception in thread "main" javax.xml.transform.TransformerException: org.apache.fop.fo.ValidationException: "fo:table-row" is missing child elements. Required content model: (table- cell+) (Keine Kontextinformationen verfügbar)
at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:786)
at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:370)
at FopReport.xmlToPdfPerXsl(FopReport.java:52)
at FopReport.main(FopReport.java:22)
Caused by: org.apache.fop.fo.ValidationException: "fo:table-row" is missing child elements. Required content model: (table-cell+) (Keine Kontextinformationen verfügbar)
at org.apache.fop.events.ValidationExceptionFactory.createException(ValidationExceptionFactory.java:38)
at org.apache.fop.events.EventExceptionManager.throwException(EventExceptionManager.java:58)
at org.apache.fop.events.DefaultEventBroadcaster$1.invoke(DefaultEventBroadcaster.java:173)
at com.sun.proxy.$Proxy2.missingChildElement(Unknown Source)
at org.apache.fop.fo.FONode.missingChildElementError(FONode.java:588)
at org.apache.fop.fo.flow.table.TableRow.finalizeNode(TableRow.java:115)
at org.apache.fop.fo.FONode.endOfNode(FONode.java:330)
at org.apache.fop.fo.flow.table.TableRow.endOfNode(TableRow.java:108)
at org.apache.fop.fo.FOTreeBuilder$MainFOHandler.endElement(FOTreeBuilder.java:360)
at org.apache.fop.fo.FOTreeBuilder.endElement(FOTreeBuilder.java:190)
at java.xml/com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler.endElement(ToXMLSAXHandler.java:263)
at java.xml/com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler.endElement(ToXMLSAXHandler.java:557)
at jdk.translet/die.verwandlung.ReportFO.table$dash$rows()
at jdk.translet/die.verwandlung.ReportFO.template$dot$3()
at jdk.translet/die.verwandlung.ReportFO.applyTemplates()
at jdk.translet/die.verwandlung.ReportFO.applyTemplates()
at jdk.translet/die.verwandlung.ReportFO.template$dot$0()
at jdk.translet/die.verwandlung.ReportFO.applyTemplates()
at jdk.translet/die.verwandlung.ReportFO.transform()
at java.xml/com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet.transform(AbstractTranslet.java:624)
at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:776)
... 3 more
---------
org.apache.fop.fo.ValidationException: "fo:table-row" is missing child elements. Required content model: (table-cell+) (Keine Kontextinformationen verfügbar)
at org.apache.fop.events.ValidationExceptionFactory.createException(ValidationExceptionFactory.java:38)
at org.apache.fop.events.EventExceptionManager.throwException(EventExceptionManager.java:58)
at org.apache.fop.events.DefaultEventBroadcaster$1.invoke(DefaultEventBroadcaster.java:173)
at com.sun.proxy.$Proxy2.missingChildElement(Unknown Source)
at org.apache.fop.fo.FONode.missingChildElementError(FONode.java:588)
at org.apache.fop.fo.flow.table.TableRow.finalizeNode(TableRow.java:115)
at org.apache.fop.fo.FONode.endOfNode(FONode.java:330)
at org.apache.fop.fo.flow.table.TableRow.endOfNode(TableRow.java:108)
at org.apache.fop.fo.FOTreeBuilder$MainFOHandler.endElement(FOTreeBuilder.java:360)
at org.apache.fop.fo.FOTreeBuilder.endElement(FOTreeBuilder.java:190)
at java.xml/com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler.endElement(ToXMLSAXHandler.java:263)
at java.xml/com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler.endElement(ToXMLSAXHandler.java:557)
at jdk.translet/die.verwandlung.ReportFO.table$dash$rows()
at jdk.translet/die.verwandlung.ReportFO.template$dot$3()
at jdk.translet/die.verwandlung.ReportFO.applyTemplates()
at jdk.translet/die.verwandlung.ReportFO.applyTemplates()
at jdk.translet/die.verwandlung.ReportFO.template$dot$0()
at jdk.translet/die.verwandlung.ReportFO.applyTemplates()
at jdk.translet/die.verwandlung.ReportFO.transform()
at java.xml/com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet.transform(AbstractTranslet.java:624)
at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:776)
at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:370)
at FopReport.xmlToPdfPerXsl(FopReport.java:52)
at FopReport.main(FopReport.java:22)
file ReportFO.pdf
image of ReportFO.pdf
xml pdf xsl-fo apache-fop
add a comment |
I transformed the XML-file ReportXHTML.xml with 2 tables to xhtml by using the xsl stylesheet ReportXHTML.xsl. As a next step I built the comparable XSL-FO file ReportFO.xsl to use it together with the modified xml-file ReportFO.xml and Apache FOP to get a PDF file, but my java application FopReport.java failed by this ValidationException
"fo:table-row" is missing child elements. Required content model:
(table-cell+)
Looking for a solution I read the XSL-Fo specification and modified the XSL-FO file by deleting the xsl-statement for-each in the xsl-template named table-rows. I got the PDF file ReportFO.pdf.
That shows that the xsl-statement for-each in the xsl-template named table-head works. The xsl-template named table-rows is comparable to it, but failed. That's my issue. What is to modify in my XSL-FO file? Thanks for your help.
file ReportXHTML.xml
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xml" href="ReportXHTML.xsl" ?>
<report>
<table>
<tableRow>
<tableHead>Name</tableHead>
<tableHead>Street</tableHead>
<tableHead>City</tableHead>
</tableRow>
<tableRow>
<entry>Torsten Horn</entry>
<entry>Hauptsr. 44</entry>
<entry>Aachen</entry>
</tableRow>
<tableRow>
<entry>Heinz Hinz</entry>
<entry>Bahnhofstr. 22</entry>
<entry>Hamburg</entry>
</tableRow>
<tableRow>
<entry>Karl Kunz</entry>
<entry>Königstr. 1</entry>
<entry>Köln</entry>
</tableRow>
</table>
<table>
<tableRow>
<tableHead>Name</tableHead>
<tableHead>City</tableHead>
</tableRow>
<tableRow>
<entry>Torsten Horn</entry>
<entry>Aachen</entry>
</tableRow>
<tableRow>
<entry>Heinz Hinz</entry>
<entry>Hamburg</entry>
</tableRow>
<tableRow>
<entry>Karl Kunz</entry>
<entry>Köln</entry>
</tableRow>
</table>
</report>
stylesheet ReportXHTML.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/1999/xhtml">
<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
<html>
<head>
<title>Report</title>
<meta http-equiv="content-type" content="text/html;charset=UTF-8"/>
</head>
<body>
<xsl:apply-templates/>
</body>
</html>
<xsl:template match="table">
<p>
<table border="1" cellspacing="0" cellpadding="5">
<tr>
<xsl:for-each select="tableRow/tableHead">
<th><xsl:apply-templates/></th>
</xsl:for-each>
</tr>
<xsl:for-each select="tableRow">
<tr>
<xsl:for-each select="entry">
<td><xsl:apply-templates/></td>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
</p>
</xsl:template>
</xsl:stylesheet>
result in FireFox:
image of result
stylesheet ReportFO.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xs:stylesheet version="1.0"
xmlns:xs="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<!-- XLS/ FO Specification see: https://www.w3.org/TR/xsl11/ -->
<!-- Attribute-Sets -->
<xs:attribute-set name="cell-style">
<xs:attribute name="border-width">0.5pt</xs:attribute>
<xs:attribute name="border-style">solid</xs:attribute>
</xs:attribute-set>
<xs:attribute-set name="block-style">
<xs:attribute name="font-size"> 10pt</xs:attribute>
<xs:attribute name="line-height">15pt</xs:attribute>
<xs:attribute name="start-indent">1mm</xs:attribute>
<xs:attribute name="end-indent"> 1mm</xs:attribute>
</xs:attribute-set>
<!-- Page Layout -->
<xs:template match="/">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="DIN-A4"
page-height="29.7cm" page-width="21cm"
margin-top="2cm" margin-bottom="1.5cm"
margin-left="2.5cm" margin-right="1.0cm">
<fo:region-body
margin-top="1.5cm" margin-bottom="1.0cm"
margin-left="0.0cm" margin-right="0.0cm"/>
<fo:region-before region-name="header" extent="1.3cm"/>
<fo:region-after region-name="footer" extent="1.0cm"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="DIN-A4">
<fo:static-content flow-name="header">
<fo:block font-size="14pt" font-family="Helvetica" font-weight="bold" text-align="left">
Report
</fo:block>
<fo:block text-align-last="justify"><fo:leader leader-pattern="rule" rule-thickness="0.5" />
</fo:block>
</fo:static-content>
<fo:static-content flow-name="footer">
<fo:block text-align-last="justify"><fo:leader leader-pattern="rule" rule-thickness="0.5" />
</fo:block>
<fo:block font-size="10pt" text-align="center" >
Page <fo:page-number/> of <fo:page-number-citation ref-id="LastPage"/>
</fo:block>
</fo:static-content>
<fo:flow flow-name="xsl-region-body">
<xs:apply-templates/>
<fo:block id="LastPage"/>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xs:template>
<!-- Table-Head -->
<xs:template name="table-head">
<fo:table-row>
<xs:for-each select="tableRow/tableHead">
<fo:table-cell xs:use-attribute-sets="cell-style">
<fo:block xs:use-attribute-sets="block-style" text-align="center">
<xs:apply-templates/>
</fo:block>
</fo:table-cell>
</xs:for-each>
</fo:table-row>
</xs:template>
<!-- Table-Rows -->
<xs:template name="table-rows">
<fo:table-row>
<xs:for-each select="tableRow/entry">
<fo:table-cell xs:use-attribute-sets="cell-style">
<fo:block xs:use-attribute-sets="block-style">
<xs:apply-templates/>
</fo:block>
</fo:table-cell>
</xs:for-each>
</fo:table-row>
</xs:template>
<!-- Table -->
<xs:template match="report/table">
<fo:block><fo:leader /></fo:block>
<fo:table border-style="solid" table-layout="fixed" width="100%">
<fo:table-header>
<xs:call-template name="table-head"/>
</fo:table-header>
<fo:table-body>
<xs:for-each select="tableRow">
<xs:call-template name="table-rows"/>
</xs:for-each>
</fo:table-body>
</fo:table>
</xs:template>
</xs:stylesheet>
modified xml-file ReportFO.xml
<?xml version="1.0" encoding="UTF-8"?>
<report>
<table>
<tableRow>
<tableHead>Name</tableHead>
etc .....
FopReport.java
import java.io.*;
import javax.xml.transform.*;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamSource;
import org.apache.fop.apps.*;
import org.apache.*;
// compile by: javac -classpath ".:lib/fop.jar:lib/xmlgraphics-commons-2.3.jar" FopReport.java
// run by:
// java -classpath ".:lib/fop.jar:lib/xmlgraphics-commons-2.3.jar:lib/commons-logging-1.0.4.jar:lib/avalon-framework-api-4.3.1.jar:lib/avalon-framework-impl-4.3.1.jar:lib/commons-io-1.3.1.jar:lib/batik-all-1.10.jar" FopReport ReportFO.xsl ReportFO.xml ReportFO.pdf
// see : https://xmlgraphics.apache.org/fop/2.3/embedding.html
public class FopReport
public static void main( String args ) throws Exception
if( args.length != 3 )
System.out.println( "Enter XSL- and XML-Inputfile, PDF-Outputfile." );
return;
FopReport.xmlToPdfPerXsl( args[0], args[1], args[2] );
System.out.println( args[0] + " + " + args[1] + " --> " + args[2] );
public static void xmlToPdfPerXsl( String inputXSL, String inputXML, String outputPDF ) throws Exception
// Step 1: Construct a FopFactory by specifying a reference to the configuration file
// (reuse if you plan to render multiple documents!)
FopFactory fopFactory = FopFactory.newInstance(new File("fop.xconf"));
// Step 2: Set up output stream
OutputStream pdf = new FileOutputStream( outputPDF );
// Step 3: Construct fop with desired output format
// Fop fop = FopFactory.newFop( MimeConstants.MIME_PDF, pdf );
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, pdf);
// Step 5: Setup input and output for XSLT transformation
// Setup input stream
Source xml = new StreamSource( inputXML );
Source xsl = new StreamSource( inputXSL );
// Resulting SAX events (the generated FO) must be piped through to FOP
Result sax = new SAXResult( fop.getDefaultHandler() );
// Step 4: Setup JAXP using identity transformer
// Transformer transformer = TransformerFactory.newInstance().newTransformer( xsl );
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer( xsl ); // identity transformer
// Step 6: Start XSLT transformation and FOP processing
transformer.transform( xml, sax );
Validation Exception
Nov. 11, 2018 7:34:05 NACHM. org.apache.fop.apps.FopConfParser configure
INFORMATION: Default page-height set to: 11in
Nov. 11, 2018 7:34:05 NACHM. org.apache.fop.apps.FopConfParser configure
INFORMATION: Default page-width set to: 8.26in
ERROR: '"fo:table-row" is missing child elements. Required content model: (table-cell+) (No context info available)'
Exception in thread "main" javax.xml.transform.TransformerException: org.apache.fop.fo.ValidationException: "fo:table-row" is missing child elements. Required content model: (table- cell+) (Keine Kontextinformationen verfügbar)
at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:786)
at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:370)
at FopReport.xmlToPdfPerXsl(FopReport.java:52)
at FopReport.main(FopReport.java:22)
Caused by: org.apache.fop.fo.ValidationException: "fo:table-row" is missing child elements. Required content model: (table-cell+) (Keine Kontextinformationen verfügbar)
at org.apache.fop.events.ValidationExceptionFactory.createException(ValidationExceptionFactory.java:38)
at org.apache.fop.events.EventExceptionManager.throwException(EventExceptionManager.java:58)
at org.apache.fop.events.DefaultEventBroadcaster$1.invoke(DefaultEventBroadcaster.java:173)
at com.sun.proxy.$Proxy2.missingChildElement(Unknown Source)
at org.apache.fop.fo.FONode.missingChildElementError(FONode.java:588)
at org.apache.fop.fo.flow.table.TableRow.finalizeNode(TableRow.java:115)
at org.apache.fop.fo.FONode.endOfNode(FONode.java:330)
at org.apache.fop.fo.flow.table.TableRow.endOfNode(TableRow.java:108)
at org.apache.fop.fo.FOTreeBuilder$MainFOHandler.endElement(FOTreeBuilder.java:360)
at org.apache.fop.fo.FOTreeBuilder.endElement(FOTreeBuilder.java:190)
at java.xml/com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler.endElement(ToXMLSAXHandler.java:263)
at java.xml/com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler.endElement(ToXMLSAXHandler.java:557)
at jdk.translet/die.verwandlung.ReportFO.table$dash$rows()
at jdk.translet/die.verwandlung.ReportFO.template$dot$3()
at jdk.translet/die.verwandlung.ReportFO.applyTemplates()
at jdk.translet/die.verwandlung.ReportFO.applyTemplates()
at jdk.translet/die.verwandlung.ReportFO.template$dot$0()
at jdk.translet/die.verwandlung.ReportFO.applyTemplates()
at jdk.translet/die.verwandlung.ReportFO.transform()
at java.xml/com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet.transform(AbstractTranslet.java:624)
at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:776)
... 3 more
---------
org.apache.fop.fo.ValidationException: "fo:table-row" is missing child elements. Required content model: (table-cell+) (Keine Kontextinformationen verfügbar)
at org.apache.fop.events.ValidationExceptionFactory.createException(ValidationExceptionFactory.java:38)
at org.apache.fop.events.EventExceptionManager.throwException(EventExceptionManager.java:58)
at org.apache.fop.events.DefaultEventBroadcaster$1.invoke(DefaultEventBroadcaster.java:173)
at com.sun.proxy.$Proxy2.missingChildElement(Unknown Source)
at org.apache.fop.fo.FONode.missingChildElementError(FONode.java:588)
at org.apache.fop.fo.flow.table.TableRow.finalizeNode(TableRow.java:115)
at org.apache.fop.fo.FONode.endOfNode(FONode.java:330)
at org.apache.fop.fo.flow.table.TableRow.endOfNode(TableRow.java:108)
at org.apache.fop.fo.FOTreeBuilder$MainFOHandler.endElement(FOTreeBuilder.java:360)
at org.apache.fop.fo.FOTreeBuilder.endElement(FOTreeBuilder.java:190)
at java.xml/com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler.endElement(ToXMLSAXHandler.java:263)
at java.xml/com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler.endElement(ToXMLSAXHandler.java:557)
at jdk.translet/die.verwandlung.ReportFO.table$dash$rows()
at jdk.translet/die.verwandlung.ReportFO.template$dot$3()
at jdk.translet/die.verwandlung.ReportFO.applyTemplates()
at jdk.translet/die.verwandlung.ReportFO.applyTemplates()
at jdk.translet/die.verwandlung.ReportFO.template$dot$0()
at jdk.translet/die.verwandlung.ReportFO.applyTemplates()
at jdk.translet/die.verwandlung.ReportFO.transform()
at java.xml/com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet.transform(AbstractTranslet.java:624)
at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:776)
at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:370)
at FopReport.xmlToPdfPerXsl(FopReport.java:52)
at FopReport.main(FopReport.java:22)
file ReportFO.pdf
image of ReportFO.pdf
xml pdf xsl-fo apache-fop
add a comment |
I transformed the XML-file ReportXHTML.xml with 2 tables to xhtml by using the xsl stylesheet ReportXHTML.xsl. As a next step I built the comparable XSL-FO file ReportFO.xsl to use it together with the modified xml-file ReportFO.xml and Apache FOP to get a PDF file, but my java application FopReport.java failed by this ValidationException
"fo:table-row" is missing child elements. Required content model:
(table-cell+)
Looking for a solution I read the XSL-Fo specification and modified the XSL-FO file by deleting the xsl-statement for-each in the xsl-template named table-rows. I got the PDF file ReportFO.pdf.
That shows that the xsl-statement for-each in the xsl-template named table-head works. The xsl-template named table-rows is comparable to it, but failed. That's my issue. What is to modify in my XSL-FO file? Thanks for your help.
file ReportXHTML.xml
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xml" href="ReportXHTML.xsl" ?>
<report>
<table>
<tableRow>
<tableHead>Name</tableHead>
<tableHead>Street</tableHead>
<tableHead>City</tableHead>
</tableRow>
<tableRow>
<entry>Torsten Horn</entry>
<entry>Hauptsr. 44</entry>
<entry>Aachen</entry>
</tableRow>
<tableRow>
<entry>Heinz Hinz</entry>
<entry>Bahnhofstr. 22</entry>
<entry>Hamburg</entry>
</tableRow>
<tableRow>
<entry>Karl Kunz</entry>
<entry>Königstr. 1</entry>
<entry>Köln</entry>
</tableRow>
</table>
<table>
<tableRow>
<tableHead>Name</tableHead>
<tableHead>City</tableHead>
</tableRow>
<tableRow>
<entry>Torsten Horn</entry>
<entry>Aachen</entry>
</tableRow>
<tableRow>
<entry>Heinz Hinz</entry>
<entry>Hamburg</entry>
</tableRow>
<tableRow>
<entry>Karl Kunz</entry>
<entry>Köln</entry>
</tableRow>
</table>
</report>
stylesheet ReportXHTML.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/1999/xhtml">
<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
<html>
<head>
<title>Report</title>
<meta http-equiv="content-type" content="text/html;charset=UTF-8"/>
</head>
<body>
<xsl:apply-templates/>
</body>
</html>
<xsl:template match="table">
<p>
<table border="1" cellspacing="0" cellpadding="5">
<tr>
<xsl:for-each select="tableRow/tableHead">
<th><xsl:apply-templates/></th>
</xsl:for-each>
</tr>
<xsl:for-each select="tableRow">
<tr>
<xsl:for-each select="entry">
<td><xsl:apply-templates/></td>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
</p>
</xsl:template>
</xsl:stylesheet>
result in FireFox:
image of result
stylesheet ReportFO.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xs:stylesheet version="1.0"
xmlns:xs="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<!-- XLS/ FO Specification see: https://www.w3.org/TR/xsl11/ -->
<!-- Attribute-Sets -->
<xs:attribute-set name="cell-style">
<xs:attribute name="border-width">0.5pt</xs:attribute>
<xs:attribute name="border-style">solid</xs:attribute>
</xs:attribute-set>
<xs:attribute-set name="block-style">
<xs:attribute name="font-size"> 10pt</xs:attribute>
<xs:attribute name="line-height">15pt</xs:attribute>
<xs:attribute name="start-indent">1mm</xs:attribute>
<xs:attribute name="end-indent"> 1mm</xs:attribute>
</xs:attribute-set>
<!-- Page Layout -->
<xs:template match="/">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="DIN-A4"
page-height="29.7cm" page-width="21cm"
margin-top="2cm" margin-bottom="1.5cm"
margin-left="2.5cm" margin-right="1.0cm">
<fo:region-body
margin-top="1.5cm" margin-bottom="1.0cm"
margin-left="0.0cm" margin-right="0.0cm"/>
<fo:region-before region-name="header" extent="1.3cm"/>
<fo:region-after region-name="footer" extent="1.0cm"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="DIN-A4">
<fo:static-content flow-name="header">
<fo:block font-size="14pt" font-family="Helvetica" font-weight="bold" text-align="left">
Report
</fo:block>
<fo:block text-align-last="justify"><fo:leader leader-pattern="rule" rule-thickness="0.5" />
</fo:block>
</fo:static-content>
<fo:static-content flow-name="footer">
<fo:block text-align-last="justify"><fo:leader leader-pattern="rule" rule-thickness="0.5" />
</fo:block>
<fo:block font-size="10pt" text-align="center" >
Page <fo:page-number/> of <fo:page-number-citation ref-id="LastPage"/>
</fo:block>
</fo:static-content>
<fo:flow flow-name="xsl-region-body">
<xs:apply-templates/>
<fo:block id="LastPage"/>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xs:template>
<!-- Table-Head -->
<xs:template name="table-head">
<fo:table-row>
<xs:for-each select="tableRow/tableHead">
<fo:table-cell xs:use-attribute-sets="cell-style">
<fo:block xs:use-attribute-sets="block-style" text-align="center">
<xs:apply-templates/>
</fo:block>
</fo:table-cell>
</xs:for-each>
</fo:table-row>
</xs:template>
<!-- Table-Rows -->
<xs:template name="table-rows">
<fo:table-row>
<xs:for-each select="tableRow/entry">
<fo:table-cell xs:use-attribute-sets="cell-style">
<fo:block xs:use-attribute-sets="block-style">
<xs:apply-templates/>
</fo:block>
</fo:table-cell>
</xs:for-each>
</fo:table-row>
</xs:template>
<!-- Table -->
<xs:template match="report/table">
<fo:block><fo:leader /></fo:block>
<fo:table border-style="solid" table-layout="fixed" width="100%">
<fo:table-header>
<xs:call-template name="table-head"/>
</fo:table-header>
<fo:table-body>
<xs:for-each select="tableRow">
<xs:call-template name="table-rows"/>
</xs:for-each>
</fo:table-body>
</fo:table>
</xs:template>
</xs:stylesheet>
modified xml-file ReportFO.xml
<?xml version="1.0" encoding="UTF-8"?>
<report>
<table>
<tableRow>
<tableHead>Name</tableHead>
etc .....
FopReport.java
import java.io.*;
import javax.xml.transform.*;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamSource;
import org.apache.fop.apps.*;
import org.apache.*;
// compile by: javac -classpath ".:lib/fop.jar:lib/xmlgraphics-commons-2.3.jar" FopReport.java
// run by:
// java -classpath ".:lib/fop.jar:lib/xmlgraphics-commons-2.3.jar:lib/commons-logging-1.0.4.jar:lib/avalon-framework-api-4.3.1.jar:lib/avalon-framework-impl-4.3.1.jar:lib/commons-io-1.3.1.jar:lib/batik-all-1.10.jar" FopReport ReportFO.xsl ReportFO.xml ReportFO.pdf
// see : https://xmlgraphics.apache.org/fop/2.3/embedding.html
public class FopReport
public static void main( String args ) throws Exception
if( args.length != 3 )
System.out.println( "Enter XSL- and XML-Inputfile, PDF-Outputfile." );
return;
FopReport.xmlToPdfPerXsl( args[0], args[1], args[2] );
System.out.println( args[0] + " + " + args[1] + " --> " + args[2] );
public static void xmlToPdfPerXsl( String inputXSL, String inputXML, String outputPDF ) throws Exception
// Step 1: Construct a FopFactory by specifying a reference to the configuration file
// (reuse if you plan to render multiple documents!)
FopFactory fopFactory = FopFactory.newInstance(new File("fop.xconf"));
// Step 2: Set up output stream
OutputStream pdf = new FileOutputStream( outputPDF );
// Step 3: Construct fop with desired output format
// Fop fop = FopFactory.newFop( MimeConstants.MIME_PDF, pdf );
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, pdf);
// Step 5: Setup input and output for XSLT transformation
// Setup input stream
Source xml = new StreamSource( inputXML );
Source xsl = new StreamSource( inputXSL );
// Resulting SAX events (the generated FO) must be piped through to FOP
Result sax = new SAXResult( fop.getDefaultHandler() );
// Step 4: Setup JAXP using identity transformer
// Transformer transformer = TransformerFactory.newInstance().newTransformer( xsl );
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer( xsl ); // identity transformer
// Step 6: Start XSLT transformation and FOP processing
transformer.transform( xml, sax );
Validation Exception
Nov. 11, 2018 7:34:05 NACHM. org.apache.fop.apps.FopConfParser configure
INFORMATION: Default page-height set to: 11in
Nov. 11, 2018 7:34:05 NACHM. org.apache.fop.apps.FopConfParser configure
INFORMATION: Default page-width set to: 8.26in
ERROR: '"fo:table-row" is missing child elements. Required content model: (table-cell+) (No context info available)'
Exception in thread "main" javax.xml.transform.TransformerException: org.apache.fop.fo.ValidationException: "fo:table-row" is missing child elements. Required content model: (table- cell+) (Keine Kontextinformationen verfügbar)
at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:786)
at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:370)
at FopReport.xmlToPdfPerXsl(FopReport.java:52)
at FopReport.main(FopReport.java:22)
Caused by: org.apache.fop.fo.ValidationException: "fo:table-row" is missing child elements. Required content model: (table-cell+) (Keine Kontextinformationen verfügbar)
at org.apache.fop.events.ValidationExceptionFactory.createException(ValidationExceptionFactory.java:38)
at org.apache.fop.events.EventExceptionManager.throwException(EventExceptionManager.java:58)
at org.apache.fop.events.DefaultEventBroadcaster$1.invoke(DefaultEventBroadcaster.java:173)
at com.sun.proxy.$Proxy2.missingChildElement(Unknown Source)
at org.apache.fop.fo.FONode.missingChildElementError(FONode.java:588)
at org.apache.fop.fo.flow.table.TableRow.finalizeNode(TableRow.java:115)
at org.apache.fop.fo.FONode.endOfNode(FONode.java:330)
at org.apache.fop.fo.flow.table.TableRow.endOfNode(TableRow.java:108)
at org.apache.fop.fo.FOTreeBuilder$MainFOHandler.endElement(FOTreeBuilder.java:360)
at org.apache.fop.fo.FOTreeBuilder.endElement(FOTreeBuilder.java:190)
at java.xml/com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler.endElement(ToXMLSAXHandler.java:263)
at java.xml/com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler.endElement(ToXMLSAXHandler.java:557)
at jdk.translet/die.verwandlung.ReportFO.table$dash$rows()
at jdk.translet/die.verwandlung.ReportFO.template$dot$3()
at jdk.translet/die.verwandlung.ReportFO.applyTemplates()
at jdk.translet/die.verwandlung.ReportFO.applyTemplates()
at jdk.translet/die.verwandlung.ReportFO.template$dot$0()
at jdk.translet/die.verwandlung.ReportFO.applyTemplates()
at jdk.translet/die.verwandlung.ReportFO.transform()
at java.xml/com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet.transform(AbstractTranslet.java:624)
at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:776)
... 3 more
---------
org.apache.fop.fo.ValidationException: "fo:table-row" is missing child elements. Required content model: (table-cell+) (Keine Kontextinformationen verfügbar)
at org.apache.fop.events.ValidationExceptionFactory.createException(ValidationExceptionFactory.java:38)
at org.apache.fop.events.EventExceptionManager.throwException(EventExceptionManager.java:58)
at org.apache.fop.events.DefaultEventBroadcaster$1.invoke(DefaultEventBroadcaster.java:173)
at com.sun.proxy.$Proxy2.missingChildElement(Unknown Source)
at org.apache.fop.fo.FONode.missingChildElementError(FONode.java:588)
at org.apache.fop.fo.flow.table.TableRow.finalizeNode(TableRow.java:115)
at org.apache.fop.fo.FONode.endOfNode(FONode.java:330)
at org.apache.fop.fo.flow.table.TableRow.endOfNode(TableRow.java:108)
at org.apache.fop.fo.FOTreeBuilder$MainFOHandler.endElement(FOTreeBuilder.java:360)
at org.apache.fop.fo.FOTreeBuilder.endElement(FOTreeBuilder.java:190)
at java.xml/com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler.endElement(ToXMLSAXHandler.java:263)
at java.xml/com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler.endElement(ToXMLSAXHandler.java:557)
at jdk.translet/die.verwandlung.ReportFO.table$dash$rows()
at jdk.translet/die.verwandlung.ReportFO.template$dot$3()
at jdk.translet/die.verwandlung.ReportFO.applyTemplates()
at jdk.translet/die.verwandlung.ReportFO.applyTemplates()
at jdk.translet/die.verwandlung.ReportFO.template$dot$0()
at jdk.translet/die.verwandlung.ReportFO.applyTemplates()
at jdk.translet/die.verwandlung.ReportFO.transform()
at java.xml/com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet.transform(AbstractTranslet.java:624)
at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:776)
at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:370)
at FopReport.xmlToPdfPerXsl(FopReport.java:52)
at FopReport.main(FopReport.java:22)
file ReportFO.pdf
image of ReportFO.pdf
xml pdf xsl-fo apache-fop
I transformed the XML-file ReportXHTML.xml with 2 tables to xhtml by using the xsl stylesheet ReportXHTML.xsl. As a next step I built the comparable XSL-FO file ReportFO.xsl to use it together with the modified xml-file ReportFO.xml and Apache FOP to get a PDF file, but my java application FopReport.java failed by this ValidationException
"fo:table-row" is missing child elements. Required content model:
(table-cell+)
Looking for a solution I read the XSL-Fo specification and modified the XSL-FO file by deleting the xsl-statement for-each in the xsl-template named table-rows. I got the PDF file ReportFO.pdf.
That shows that the xsl-statement for-each in the xsl-template named table-head works. The xsl-template named table-rows is comparable to it, but failed. That's my issue. What is to modify in my XSL-FO file? Thanks for your help.
file ReportXHTML.xml
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xml" href="ReportXHTML.xsl" ?>
<report>
<table>
<tableRow>
<tableHead>Name</tableHead>
<tableHead>Street</tableHead>
<tableHead>City</tableHead>
</tableRow>
<tableRow>
<entry>Torsten Horn</entry>
<entry>Hauptsr. 44</entry>
<entry>Aachen</entry>
</tableRow>
<tableRow>
<entry>Heinz Hinz</entry>
<entry>Bahnhofstr. 22</entry>
<entry>Hamburg</entry>
</tableRow>
<tableRow>
<entry>Karl Kunz</entry>
<entry>Königstr. 1</entry>
<entry>Köln</entry>
</tableRow>
</table>
<table>
<tableRow>
<tableHead>Name</tableHead>
<tableHead>City</tableHead>
</tableRow>
<tableRow>
<entry>Torsten Horn</entry>
<entry>Aachen</entry>
</tableRow>
<tableRow>
<entry>Heinz Hinz</entry>
<entry>Hamburg</entry>
</tableRow>
<tableRow>
<entry>Karl Kunz</entry>
<entry>Köln</entry>
</tableRow>
</table>
</report>
stylesheet ReportXHTML.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/1999/xhtml">
<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
<html>
<head>
<title>Report</title>
<meta http-equiv="content-type" content="text/html;charset=UTF-8"/>
</head>
<body>
<xsl:apply-templates/>
</body>
</html>
<xsl:template match="table">
<p>
<table border="1" cellspacing="0" cellpadding="5">
<tr>
<xsl:for-each select="tableRow/tableHead">
<th><xsl:apply-templates/></th>
</xsl:for-each>
</tr>
<xsl:for-each select="tableRow">
<tr>
<xsl:for-each select="entry">
<td><xsl:apply-templates/></td>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
</p>
</xsl:template>
</xsl:stylesheet>
result in FireFox:
image of result
stylesheet ReportFO.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xs:stylesheet version="1.0"
xmlns:xs="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<!-- XLS/ FO Specification see: https://www.w3.org/TR/xsl11/ -->
<!-- Attribute-Sets -->
<xs:attribute-set name="cell-style">
<xs:attribute name="border-width">0.5pt</xs:attribute>
<xs:attribute name="border-style">solid</xs:attribute>
</xs:attribute-set>
<xs:attribute-set name="block-style">
<xs:attribute name="font-size"> 10pt</xs:attribute>
<xs:attribute name="line-height">15pt</xs:attribute>
<xs:attribute name="start-indent">1mm</xs:attribute>
<xs:attribute name="end-indent"> 1mm</xs:attribute>
</xs:attribute-set>
<!-- Page Layout -->
<xs:template match="/">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="DIN-A4"
page-height="29.7cm" page-width="21cm"
margin-top="2cm" margin-bottom="1.5cm"
margin-left="2.5cm" margin-right="1.0cm">
<fo:region-body
margin-top="1.5cm" margin-bottom="1.0cm"
margin-left="0.0cm" margin-right="0.0cm"/>
<fo:region-before region-name="header" extent="1.3cm"/>
<fo:region-after region-name="footer" extent="1.0cm"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="DIN-A4">
<fo:static-content flow-name="header">
<fo:block font-size="14pt" font-family="Helvetica" font-weight="bold" text-align="left">
Report
</fo:block>
<fo:block text-align-last="justify"><fo:leader leader-pattern="rule" rule-thickness="0.5" />
</fo:block>
</fo:static-content>
<fo:static-content flow-name="footer">
<fo:block text-align-last="justify"><fo:leader leader-pattern="rule" rule-thickness="0.5" />
</fo:block>
<fo:block font-size="10pt" text-align="center" >
Page <fo:page-number/> of <fo:page-number-citation ref-id="LastPage"/>
</fo:block>
</fo:static-content>
<fo:flow flow-name="xsl-region-body">
<xs:apply-templates/>
<fo:block id="LastPage"/>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xs:template>
<!-- Table-Head -->
<xs:template name="table-head">
<fo:table-row>
<xs:for-each select="tableRow/tableHead">
<fo:table-cell xs:use-attribute-sets="cell-style">
<fo:block xs:use-attribute-sets="block-style" text-align="center">
<xs:apply-templates/>
</fo:block>
</fo:table-cell>
</xs:for-each>
</fo:table-row>
</xs:template>
<!-- Table-Rows -->
<xs:template name="table-rows">
<fo:table-row>
<xs:for-each select="tableRow/entry">
<fo:table-cell xs:use-attribute-sets="cell-style">
<fo:block xs:use-attribute-sets="block-style">
<xs:apply-templates/>
</fo:block>
</fo:table-cell>
</xs:for-each>
</fo:table-row>
</xs:template>
<!-- Table -->
<xs:template match="report/table">
<fo:block><fo:leader /></fo:block>
<fo:table border-style="solid" table-layout="fixed" width="100%">
<fo:table-header>
<xs:call-template name="table-head"/>
</fo:table-header>
<fo:table-body>
<xs:for-each select="tableRow">
<xs:call-template name="table-rows"/>
</xs:for-each>
</fo:table-body>
</fo:table>
</xs:template>
</xs:stylesheet>
modified xml-file ReportFO.xml
<?xml version="1.0" encoding="UTF-8"?>
<report>
<table>
<tableRow>
<tableHead>Name</tableHead>
etc .....
FopReport.java
import java.io.*;
import javax.xml.transform.*;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamSource;
import org.apache.fop.apps.*;
import org.apache.*;
// compile by: javac -classpath ".:lib/fop.jar:lib/xmlgraphics-commons-2.3.jar" FopReport.java
// run by:
// java -classpath ".:lib/fop.jar:lib/xmlgraphics-commons-2.3.jar:lib/commons-logging-1.0.4.jar:lib/avalon-framework-api-4.3.1.jar:lib/avalon-framework-impl-4.3.1.jar:lib/commons-io-1.3.1.jar:lib/batik-all-1.10.jar" FopReport ReportFO.xsl ReportFO.xml ReportFO.pdf
// see : https://xmlgraphics.apache.org/fop/2.3/embedding.html
public class FopReport
public static void main( String args ) throws Exception
if( args.length != 3 )
System.out.println( "Enter XSL- and XML-Inputfile, PDF-Outputfile." );
return;
FopReport.xmlToPdfPerXsl( args[0], args[1], args[2] );
System.out.println( args[0] + " + " + args[1] + " --> " + args[2] );
public static void xmlToPdfPerXsl( String inputXSL, String inputXML, String outputPDF ) throws Exception
// Step 1: Construct a FopFactory by specifying a reference to the configuration file
// (reuse if you plan to render multiple documents!)
FopFactory fopFactory = FopFactory.newInstance(new File("fop.xconf"));
// Step 2: Set up output stream
OutputStream pdf = new FileOutputStream( outputPDF );
// Step 3: Construct fop with desired output format
// Fop fop = FopFactory.newFop( MimeConstants.MIME_PDF, pdf );
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, pdf);
// Step 5: Setup input and output for XSLT transformation
// Setup input stream
Source xml = new StreamSource( inputXML );
Source xsl = new StreamSource( inputXSL );
// Resulting SAX events (the generated FO) must be piped through to FOP
Result sax = new SAXResult( fop.getDefaultHandler() );
// Step 4: Setup JAXP using identity transformer
// Transformer transformer = TransformerFactory.newInstance().newTransformer( xsl );
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer( xsl ); // identity transformer
// Step 6: Start XSLT transformation and FOP processing
transformer.transform( xml, sax );
Validation Exception
Nov. 11, 2018 7:34:05 NACHM. org.apache.fop.apps.FopConfParser configure
INFORMATION: Default page-height set to: 11in
Nov. 11, 2018 7:34:05 NACHM. org.apache.fop.apps.FopConfParser configure
INFORMATION: Default page-width set to: 8.26in
ERROR: '"fo:table-row" is missing child elements. Required content model: (table-cell+) (No context info available)'
Exception in thread "main" javax.xml.transform.TransformerException: org.apache.fop.fo.ValidationException: "fo:table-row" is missing child elements. Required content model: (table- cell+) (Keine Kontextinformationen verfügbar)
at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:786)
at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:370)
at FopReport.xmlToPdfPerXsl(FopReport.java:52)
at FopReport.main(FopReport.java:22)
Caused by: org.apache.fop.fo.ValidationException: "fo:table-row" is missing child elements. Required content model: (table-cell+) (Keine Kontextinformationen verfügbar)
at org.apache.fop.events.ValidationExceptionFactory.createException(ValidationExceptionFactory.java:38)
at org.apache.fop.events.EventExceptionManager.throwException(EventExceptionManager.java:58)
at org.apache.fop.events.DefaultEventBroadcaster$1.invoke(DefaultEventBroadcaster.java:173)
at com.sun.proxy.$Proxy2.missingChildElement(Unknown Source)
at org.apache.fop.fo.FONode.missingChildElementError(FONode.java:588)
at org.apache.fop.fo.flow.table.TableRow.finalizeNode(TableRow.java:115)
at org.apache.fop.fo.FONode.endOfNode(FONode.java:330)
at org.apache.fop.fo.flow.table.TableRow.endOfNode(TableRow.java:108)
at org.apache.fop.fo.FOTreeBuilder$MainFOHandler.endElement(FOTreeBuilder.java:360)
at org.apache.fop.fo.FOTreeBuilder.endElement(FOTreeBuilder.java:190)
at java.xml/com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler.endElement(ToXMLSAXHandler.java:263)
at java.xml/com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler.endElement(ToXMLSAXHandler.java:557)
at jdk.translet/die.verwandlung.ReportFO.table$dash$rows()
at jdk.translet/die.verwandlung.ReportFO.template$dot$3()
at jdk.translet/die.verwandlung.ReportFO.applyTemplates()
at jdk.translet/die.verwandlung.ReportFO.applyTemplates()
at jdk.translet/die.verwandlung.ReportFO.template$dot$0()
at jdk.translet/die.verwandlung.ReportFO.applyTemplates()
at jdk.translet/die.verwandlung.ReportFO.transform()
at java.xml/com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet.transform(AbstractTranslet.java:624)
at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:776)
... 3 more
---------
org.apache.fop.fo.ValidationException: "fo:table-row" is missing child elements. Required content model: (table-cell+) (Keine Kontextinformationen verfügbar)
at org.apache.fop.events.ValidationExceptionFactory.createException(ValidationExceptionFactory.java:38)
at org.apache.fop.events.EventExceptionManager.throwException(EventExceptionManager.java:58)
at org.apache.fop.events.DefaultEventBroadcaster$1.invoke(DefaultEventBroadcaster.java:173)
at com.sun.proxy.$Proxy2.missingChildElement(Unknown Source)
at org.apache.fop.fo.FONode.missingChildElementError(FONode.java:588)
at org.apache.fop.fo.flow.table.TableRow.finalizeNode(TableRow.java:115)
at org.apache.fop.fo.FONode.endOfNode(FONode.java:330)
at org.apache.fop.fo.flow.table.TableRow.endOfNode(TableRow.java:108)
at org.apache.fop.fo.FOTreeBuilder$MainFOHandler.endElement(FOTreeBuilder.java:360)
at org.apache.fop.fo.FOTreeBuilder.endElement(FOTreeBuilder.java:190)
at java.xml/com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler.endElement(ToXMLSAXHandler.java:263)
at java.xml/com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler.endElement(ToXMLSAXHandler.java:557)
at jdk.translet/die.verwandlung.ReportFO.table$dash$rows()
at jdk.translet/die.verwandlung.ReportFO.template$dot$3()
at jdk.translet/die.verwandlung.ReportFO.applyTemplates()
at jdk.translet/die.verwandlung.ReportFO.applyTemplates()
at jdk.translet/die.verwandlung.ReportFO.template$dot$0()
at jdk.translet/die.verwandlung.ReportFO.applyTemplates()
at jdk.translet/die.verwandlung.ReportFO.transform()
at java.xml/com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet.transform(AbstractTranslet.java:624)
at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:776)
at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:370)
at FopReport.xmlToPdfPerXsl(FopReport.java:52)
at FopReport.main(FopReport.java:22)
file ReportFO.pdf
image of ReportFO.pdf
xml pdf xsl-fo apache-fop
xml pdf xsl-fo apache-fop
asked Nov 11 '18 at 18:57
FriziFrizi
75
75
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
Here, the xs:for-each
is changing the context to each tableRow/entry
in turn and calling the 'table-rows' template with the current tableRow
as the context item:
<xs:for-each select="tableRow">
<xs:call-template name="table-rows"/>
</xs:for-each>
Here, the xs:for-each
is changing the context to each entry
child of each tableRow
child of the context item:
<!-- Table-Rows -->
<xs:template name="table-rows">
<fo:table-row>
<xs:for-each select="tableRow/entry">
<fo:table-cell xs:use-attribute-sets="cell-style">
<fo:block xs:use-attribute-sets="block-style">
<xs:apply-templates/>
</fo:block>
</fo:table-cell>
</xs:for-each>
When the context is a tableRow
, there is no tableRow/entry
to select.
The quick solution is to remove the tableRow
in tableRow/entry
.
I suggest that the longer term solution would be to do more with xs:apply-templates
and less with xs:for-each
. If you had used xs:apply-templates
, then the XSLT processor would have selected the child elements each time and then found the best matching xs:template
to use for each element. Something like (untested):
<xs:template match="table">
<fo:table>
<fo:table-header>
<xs:apply-templates select="tableRow[tableHead]" />
</fo:table-header>
<fo:table-body>
<xs:apply-templates select="tableRow[entry]" />
</fo:table-body>
</fo:table>
</xs:template>
<xs:template match="tableRow">
<fo:table-row>
<xs:apply-templates />
</fo:table-row>
</xs:template>
<xs:template match="tableHead">
<fo:table-cell xs:use-attribute-sets="cell-style">
<fo:block xs:use-attribute-sets="block-style" text-align="center">
<xs:apply-templates/>
</fo:block>
</fo:table-cell>
</xs:template>
<xs:template match="entry">
<fo:table-cell xs:use-attribute-sets="cell-style">
<fo:block xs:use-attribute-sets="block-style">
<xs:apply-templates/>
</fo:block>
</fo:table-cell>
</xs:template>
Your suggestion is fine: I modified in the template table-row your statement<xs:apply-templates" />
to<xs:apply-templates />
and it worked. Thanks for your help.
– Frizi
Nov 11 '18 at 21:28
Thanks. Now fixed.
– Tony Graham
Nov 12 '18 at 8:32
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53252107%2fhow-to-transform-different-tables-in-a-xml-file-to-pdf-by-using-a-xsl-fo-stylesh%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Here, the xs:for-each
is changing the context to each tableRow/entry
in turn and calling the 'table-rows' template with the current tableRow
as the context item:
<xs:for-each select="tableRow">
<xs:call-template name="table-rows"/>
</xs:for-each>
Here, the xs:for-each
is changing the context to each entry
child of each tableRow
child of the context item:
<!-- Table-Rows -->
<xs:template name="table-rows">
<fo:table-row>
<xs:for-each select="tableRow/entry">
<fo:table-cell xs:use-attribute-sets="cell-style">
<fo:block xs:use-attribute-sets="block-style">
<xs:apply-templates/>
</fo:block>
</fo:table-cell>
</xs:for-each>
When the context is a tableRow
, there is no tableRow/entry
to select.
The quick solution is to remove the tableRow
in tableRow/entry
.
I suggest that the longer term solution would be to do more with xs:apply-templates
and less with xs:for-each
. If you had used xs:apply-templates
, then the XSLT processor would have selected the child elements each time and then found the best matching xs:template
to use for each element. Something like (untested):
<xs:template match="table">
<fo:table>
<fo:table-header>
<xs:apply-templates select="tableRow[tableHead]" />
</fo:table-header>
<fo:table-body>
<xs:apply-templates select="tableRow[entry]" />
</fo:table-body>
</fo:table>
</xs:template>
<xs:template match="tableRow">
<fo:table-row>
<xs:apply-templates />
</fo:table-row>
</xs:template>
<xs:template match="tableHead">
<fo:table-cell xs:use-attribute-sets="cell-style">
<fo:block xs:use-attribute-sets="block-style" text-align="center">
<xs:apply-templates/>
</fo:block>
</fo:table-cell>
</xs:template>
<xs:template match="entry">
<fo:table-cell xs:use-attribute-sets="cell-style">
<fo:block xs:use-attribute-sets="block-style">
<xs:apply-templates/>
</fo:block>
</fo:table-cell>
</xs:template>
Your suggestion is fine: I modified in the template table-row your statement<xs:apply-templates" />
to<xs:apply-templates />
and it worked. Thanks for your help.
– Frizi
Nov 11 '18 at 21:28
Thanks. Now fixed.
– Tony Graham
Nov 12 '18 at 8:32
add a comment |
Here, the xs:for-each
is changing the context to each tableRow/entry
in turn and calling the 'table-rows' template with the current tableRow
as the context item:
<xs:for-each select="tableRow">
<xs:call-template name="table-rows"/>
</xs:for-each>
Here, the xs:for-each
is changing the context to each entry
child of each tableRow
child of the context item:
<!-- Table-Rows -->
<xs:template name="table-rows">
<fo:table-row>
<xs:for-each select="tableRow/entry">
<fo:table-cell xs:use-attribute-sets="cell-style">
<fo:block xs:use-attribute-sets="block-style">
<xs:apply-templates/>
</fo:block>
</fo:table-cell>
</xs:for-each>
When the context is a tableRow
, there is no tableRow/entry
to select.
The quick solution is to remove the tableRow
in tableRow/entry
.
I suggest that the longer term solution would be to do more with xs:apply-templates
and less with xs:for-each
. If you had used xs:apply-templates
, then the XSLT processor would have selected the child elements each time and then found the best matching xs:template
to use for each element. Something like (untested):
<xs:template match="table">
<fo:table>
<fo:table-header>
<xs:apply-templates select="tableRow[tableHead]" />
</fo:table-header>
<fo:table-body>
<xs:apply-templates select="tableRow[entry]" />
</fo:table-body>
</fo:table>
</xs:template>
<xs:template match="tableRow">
<fo:table-row>
<xs:apply-templates />
</fo:table-row>
</xs:template>
<xs:template match="tableHead">
<fo:table-cell xs:use-attribute-sets="cell-style">
<fo:block xs:use-attribute-sets="block-style" text-align="center">
<xs:apply-templates/>
</fo:block>
</fo:table-cell>
</xs:template>
<xs:template match="entry">
<fo:table-cell xs:use-attribute-sets="cell-style">
<fo:block xs:use-attribute-sets="block-style">
<xs:apply-templates/>
</fo:block>
</fo:table-cell>
</xs:template>
Your suggestion is fine: I modified in the template table-row your statement<xs:apply-templates" />
to<xs:apply-templates />
and it worked. Thanks for your help.
– Frizi
Nov 11 '18 at 21:28
Thanks. Now fixed.
– Tony Graham
Nov 12 '18 at 8:32
add a comment |
Here, the xs:for-each
is changing the context to each tableRow/entry
in turn and calling the 'table-rows' template with the current tableRow
as the context item:
<xs:for-each select="tableRow">
<xs:call-template name="table-rows"/>
</xs:for-each>
Here, the xs:for-each
is changing the context to each entry
child of each tableRow
child of the context item:
<!-- Table-Rows -->
<xs:template name="table-rows">
<fo:table-row>
<xs:for-each select="tableRow/entry">
<fo:table-cell xs:use-attribute-sets="cell-style">
<fo:block xs:use-attribute-sets="block-style">
<xs:apply-templates/>
</fo:block>
</fo:table-cell>
</xs:for-each>
When the context is a tableRow
, there is no tableRow/entry
to select.
The quick solution is to remove the tableRow
in tableRow/entry
.
I suggest that the longer term solution would be to do more with xs:apply-templates
and less with xs:for-each
. If you had used xs:apply-templates
, then the XSLT processor would have selected the child elements each time and then found the best matching xs:template
to use for each element. Something like (untested):
<xs:template match="table">
<fo:table>
<fo:table-header>
<xs:apply-templates select="tableRow[tableHead]" />
</fo:table-header>
<fo:table-body>
<xs:apply-templates select="tableRow[entry]" />
</fo:table-body>
</fo:table>
</xs:template>
<xs:template match="tableRow">
<fo:table-row>
<xs:apply-templates />
</fo:table-row>
</xs:template>
<xs:template match="tableHead">
<fo:table-cell xs:use-attribute-sets="cell-style">
<fo:block xs:use-attribute-sets="block-style" text-align="center">
<xs:apply-templates/>
</fo:block>
</fo:table-cell>
</xs:template>
<xs:template match="entry">
<fo:table-cell xs:use-attribute-sets="cell-style">
<fo:block xs:use-attribute-sets="block-style">
<xs:apply-templates/>
</fo:block>
</fo:table-cell>
</xs:template>
Here, the xs:for-each
is changing the context to each tableRow/entry
in turn and calling the 'table-rows' template with the current tableRow
as the context item:
<xs:for-each select="tableRow">
<xs:call-template name="table-rows"/>
</xs:for-each>
Here, the xs:for-each
is changing the context to each entry
child of each tableRow
child of the context item:
<!-- Table-Rows -->
<xs:template name="table-rows">
<fo:table-row>
<xs:for-each select="tableRow/entry">
<fo:table-cell xs:use-attribute-sets="cell-style">
<fo:block xs:use-attribute-sets="block-style">
<xs:apply-templates/>
</fo:block>
</fo:table-cell>
</xs:for-each>
When the context is a tableRow
, there is no tableRow/entry
to select.
The quick solution is to remove the tableRow
in tableRow/entry
.
I suggest that the longer term solution would be to do more with xs:apply-templates
and less with xs:for-each
. If you had used xs:apply-templates
, then the XSLT processor would have selected the child elements each time and then found the best matching xs:template
to use for each element. Something like (untested):
<xs:template match="table">
<fo:table>
<fo:table-header>
<xs:apply-templates select="tableRow[tableHead]" />
</fo:table-header>
<fo:table-body>
<xs:apply-templates select="tableRow[entry]" />
</fo:table-body>
</fo:table>
</xs:template>
<xs:template match="tableRow">
<fo:table-row>
<xs:apply-templates />
</fo:table-row>
</xs:template>
<xs:template match="tableHead">
<fo:table-cell xs:use-attribute-sets="cell-style">
<fo:block xs:use-attribute-sets="block-style" text-align="center">
<xs:apply-templates/>
</fo:block>
</fo:table-cell>
</xs:template>
<xs:template match="entry">
<fo:table-cell xs:use-attribute-sets="cell-style">
<fo:block xs:use-attribute-sets="block-style">
<xs:apply-templates/>
</fo:block>
</fo:table-cell>
</xs:template>
edited Nov 11 '18 at 21:53
answered Nov 11 '18 at 20:17
Tony GrahamTony Graham
4,111717
4,111717
Your suggestion is fine: I modified in the template table-row your statement<xs:apply-templates" />
to<xs:apply-templates />
and it worked. Thanks for your help.
– Frizi
Nov 11 '18 at 21:28
Thanks. Now fixed.
– Tony Graham
Nov 12 '18 at 8:32
add a comment |
Your suggestion is fine: I modified in the template table-row your statement<xs:apply-templates" />
to<xs:apply-templates />
and it worked. Thanks for your help.
– Frizi
Nov 11 '18 at 21:28
Thanks. Now fixed.
– Tony Graham
Nov 12 '18 at 8:32
Your suggestion is fine: I modified in the template table-row your statement
<xs:apply-templates" />
to <xs:apply-templates />
and it worked. Thanks for your help.– Frizi
Nov 11 '18 at 21:28
Your suggestion is fine: I modified in the template table-row your statement
<xs:apply-templates" />
to <xs:apply-templates />
and it worked. Thanks for your help.– Frizi
Nov 11 '18 at 21:28
Thanks. Now fixed.
– Tony Graham
Nov 12 '18 at 8:32
Thanks. Now fixed.
– Tony Graham
Nov 12 '18 at 8:32
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53252107%2fhow-to-transform-different-tables-in-a-xml-file-to-pdf-by-using-a-xsl-fo-stylesh%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown