XMLMill - convert xml to pdf with java. Generate PDF from xml/xsl.

XMLMill User Guide

Version: 3.00 Date: January 2nd, 2008
This tutorial is opened in a separate window in order to maximize the legibility of this tutorial.
To return to XMLMill, close this browser window

This page as PDFPrinter friendly pageThis guide (!) as PDF

XMLMill API

XMLMill can directly be used in Java applications, using the public classes in the API. The API contains various packages:

com.xmlmill

Contains various classes that can be called to generate PDF documents from within your Java application.

com.xmlmill.applet

Contains the main class to be called when using XMLMill interactively (see the XMLMill Interactive chapter).

com.xmlmill.batch

Contains the main class to be called when using XMLMill in batch (see the XMLMill Batch chapter).

com.xmlmill.config

Contains the Configuration class responsible for reading the configuration properties from an (external) XML configuration file and making these available to the application.

com.xmlmill.connector.*

Contains various connectors to simplify use of XMLMill with other applications (see the XMLMill Connectors chapter.

com.xmlmill.exception

Contains the exception classes used by XMLMill.

  • For a detailed overview of the methods available in each class please visit the JavaDoc in the doc directory.

Package: com.xmlmill

Class: JAXPTransformer

The most important class in this package is the JAXPTransformer class.

An instance of this class will be responsible for generating a .pdf document based on the xml/xsl data provided.

The xml and xsl data can be provided to the JAXPTransformer instance as a:

java.io.File instance

The data is located in a File on the filesystem.

java.io.InputStream instance

The data is passed as a Stream object.

java.io.Reader instance

The data is passed as a Reader object.

java.net.URL instance

The data is passed as a URL object.

org.w3c.dom.Document instance

The data is passed as a org.w3c.dom.Document object.

Following steps need to be executed to succesfully generate a .pdf document:

  1. Create a new JAXPTransformer instance, using the JAXPTransformer() default constructor.
  2. Define how the xml-data is sent to the instance, using one of the overloaded setXMLDocument(...) methods.
  3. Define how the xsl-data is sent to the instance, using one of the overloaded setXSLDocument(...) methods.
  4. Define where images and other resources resides on the server (used during generation) using one of the overloaded setBaseURL(...) methods.
  5. Define where the generated .pdf document should be sent to, using the setOutputStream(java.io.OutputStream) method.
  6. Perform the transformation using the transform() method of the created JAXPTransformer instance.

Following steps are optional:

  1. Define an errorhandler instance using the setErrorHandler(JAXPErrorHandler) method.
  2. Define the configuration file using the Configurator.configure() method.

Any transformation that needs to be performed will be done by calling the transform() method of an instance of the JAXPTransformer class.

  • Please check the Javadoc api to understand all methods this class offers. The JAXPTransformer class has all the methods needed to call XMLMill from within any situation.

Defining the Base URL

The setBaseURL(...) method is used by the underlying xml-parser and xsl-transformer to resolve the relative URIs and paths mentioned in the .xml and .xsl data.

The setBaseURL(...) should point to the resources referenced in the xml/xsl-data (images, other xsl-files, ...).

Methods

The JAXPTransformer class has four overloaded methods to define the base URI against which relative URIs and paths mentioned in the .xml and .xsl document are resolved:

setBaseURL(java.lang.String)

The base URL should be defined as a URI (if it is a URL, it must be fully resolved (it may not be a relative URL)).

setBaseURL(java.io.File)

Define the base URL using a java.io.File instance. If the xml-file is in the same directory as the xmlmill.dtd, the parameter can be the xml java.io.File instance. If the xml-data are referenced by a java.io.InputStreamor java.io.Reader instance, the java.io.file object should point to (the directory where) the xmlmill.dtd (resides).

setBaseURL(java.lang.String)

The base URL should be defined as a URI (if it is a URL, it must be fully resolved (it may not be a relative URL)).

setBaseURL(java.io.File)

Define the base URL using a java.io.File instance. If the xsl-file is in the same directory as the resources, the parameter can be the xsl java.io.File instance. If the xsl-data are referenced by a java.io.InputStreamor java.io.Reader instance, the java.io.file object should point to a directory where the resrouces resides or should point to a specific resource (e.g. an image file).

  • Prefer to use a URI rather than a system-dependent file reference. For example: prefer to pass as parameter "file:/C:/Data/XMLMill/Website/testservlet/xmlxsl" instead of "C:\\Data\\XMLMill\\Website\\testservlet\\xmlxsl".
  • Always use a fully resolved URI.

Defining global stylesheet parameters

Defining global stylesheet parameters

With the setStylesheetParam method top-level (global) xsl stylesheet parameters can be defined at run-time.

Method: setStylesheetParam(String key, Object expression)

This method allows to define dynamically (at run-time) top-level (global) xsl stylesheet parameters.

The key parameter defines the name of the global parameter, the expression parameter defines the expression.

The example below passes two parameters from a servlet to a .xsl stylesheet:

[001] public class SortOutput extends HttpServlet
[002] {
[003] 
[004]   public void doGet(HttpServletRequest request, HttpServletResponse 
        response)
[006]          throws ServletException, IOException
[007]   {
[008]      String realpath = this.getServletContext().getRealPath("/xmlxsl/");
[009] 
[010]      JAXPTransformer transform; 
[011] 
[012]       try
[013]       {
[014]         // Tomcat 4.0.4 server
[015]         File xmlfile = new File(realpath + "/" 
              +request.getParameter("xml"));
[017]         File xslfile = new File(realpath + "/" 
              request.getParameter("xsl"));
[019] 
[020]         // Get run-time parameters   
[021]         String sortparam = request.getParameter("sortparam"); 
[022]         String sortorder = request.getParameter("sortorder");
[023] 
[024]         // Set ContentType
[025]         response.setContentType("application/pdf");
[026]          
[027]         //Get the output stream
[028]         javax.servlet.ServletOutputStream ostream = 
              response.getOutputStream();
[030] 
[031]         // Now transform XML and XSL file ...
[032]         transform = new JAXPTransformer();
[033] 
[034]         transform.setXMLFile(xmlfile);
[035] 
[036]         transform.setXSLFile(xslfile);
[037] 
[038]         // Set transform outputstream
[039]         transform.setOutputStream(ostream);
[040] 
[041]         // Pass parameter(s) 
[042]         transform.setStylesheetParam("sortcolumn", sortparam);
[043]         transform.setStylesheetParam("sortorder", sortorder); 
[044] 
[045]         // and transform. 
[046]         transform.transform();
[047] 
[048]         ...  
[049]     

1

The parameters are dynamically defined via the HttpServletRequest object.

2

The parameters are passed to the JAXPTransformer instance using the setStylesheetParam() method, before calling the transform() method.

3

The transformation is done.

  • To pass more than one parameter, call the setStylesheetParam for each parameter separately.

In order to pass the parameter(s) to the .xsl file, the .xsl needs to have defined corresponding top-level (global) parameters:

[001] 
[002] <?xml version="1.0" encoding="UTF-16" ?> 
[003]  <xsl:stylesheet version="1.0"   
[004]     xmlns:ml="http://www.xmlmill.com/XSL/Format"
[005]     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
[006]     xsi:schemaLocation="http://www.xmlmill.com/XSL/Format 
          ../../docs/xsd/xmlmill.xsd"
[008]     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
[009]   >
[010]     
[011]   <xsl:output method="xml" indent="yes"  encoding="UTF-16"/>
[012]   <xsl:param name="sortcolumn"/> 
[013]   <xsl:param name="sortorder"/>      
[014]   ...
[015]     

1

Top-level (global) parameters are defined in the .xsl stylesheet with names corresponding to the keys defined in the calling progam.

As the parameters are global they will be visible in any template in the .xsl stylesheet.

JAXP 1.3 specific methods

Following methods can only be used if you have a JAXP 1.3 implementation of an xml-parser and xsl-transformer (the corresponding get methods are omitted for brevity):

void setTemplates()

Defines a javax.xml.transform.Templates instance used to define an internal javax.xml.transform.Transformer instance. If a Templates instance is defined, it will take precedence over a xsl-stylesheet defined in an xml document (using the <?xml-stylesheet href="..." type="text/xsl"?> tag).

  • You need a JAXP 1.3 compliant implementation to use this method successfully

void setSchema()

Defines a javax.xml.validation.Schema instance. The javax.xml.validation.Schema class is an "immutable" memory representation of schema. Once the schemas are loaded into memory and represented as a Schema instance, it can be used for validation. In this way, a single Schema instance can be shared with many different parser instances even running in different threads. Applications are encouraged to be written so that the same set of schema are parsed only once and the same Schema instance is passed to different instances of the parser.

  • You need a JAXP 1.3 compliant implementation to use this method successfully

void setSchemaLocation()

Defines a javax.xml.validation.Schema to use to validate the result-tree against

  • You need a JAXP 1.3 compliant implementation to use this method successfully

Class: JAXPErrorHandler

This class implements the org.xml.sax.ErrorHandler interface.

This way all errors that occur during .pdf generation follow the same logic as the org.xml.sax.ErrorHandler class.

With this class you only need one errorhandler instance to detect parsing errors (thrown by the SAX handler beneath XMLMill) and .pdf generation errors (thrown by XMLMill). Following methods are available:

public JAXPErrorHandler()

This is the default constructor that mimics the default behavior of a SAX2 compliant parser. This means:

  • FatalErrors are always logged and aborted.
  • If a separate errorhandler instance is not added to the JAXPTransformer instance, a default errorhandler will be used that will mimic the default behavior of a SAX2 compliant parser.

public JAXPErrorHandler(int flags)

Construct an instance of this class and define the behavior using following class' constants:

ABORT_ON_ERROR

Abort when a recoverable parser error has occured (value = 2).

ABORT_ON_WARNING

Abort when a warning has occured (value = 8).

The flags parameter is the sum of above values, indicating which errors to log and to abort on.

public void error (org.xml.sax.SAXParseException)

This method is used to report errors that aren't expected to be fatal. The best-known example is violation of XML validity constraints. Not many application-level errors (as reported by XMLMill) will fall into this category as XMLMill's errors will be warnings or fatalErrors.

public void fatalerror (org.xml.sax.SAXParseException)

This method is used to report errors, typically violations of well formedness, that are fatal. Most application-level errors (as reported by XMLMill) will fall into this category. Parsing (and therefore generation of the .pdf document) is aborted.

public void warning (org.xml.sax.SAXParseException)

This method is used to report warnings. Unlike fatal and nonfatal errors, the XML specification doesn't place requirements on reporting such situations. XMLMill will generate warnings when attributes have the wrong value or attributes are not recognized.

Package: com.xmlmill.config

This package contains only one class to be used, the Configurator class.

Class: Configurator

The Configurator class is responsible for:

  • Define the logging instance to use.
  • Reading the configuration properties from an (external) XML configuration file and make these available to the application.
  • Overrule the JAXP version defined in the configuration file to use when parsing xml and transforming xsl documents.

static void setLogger()

The setLogger method is used to define the logging instance to use by XMLMill to send the logmessages to.

The passed logging instance must implement the org.apache.commons.logging.Log interface class.

  • Always call this method before calling the configure() (or one of its overloaded) methods.

static void configure()

The configure method is overloaded in order to define:

  1. The location of the configuration file (config.xml) to use.
  2. The version of the underlying JAXP implementation used.
  3. The logging instance to use (using the setLogger() method.

Eight overloaded configure() methods are available:

Method Explanation
configure() 1) Load the configuration values from the default build-in config.xml.
2) Use the JAXP version as defined in the default config.xml file.
configure(int i) 1) Load the configuration values from the default build-in config.xml.
2) Use the JAXP version passed as parameter. The allowed parameters are: Configure.JAXP_12, Configure.JAXP_13
configure(File f)
configure(String s)
configure(URL urll)
1) Load the configuration values from the specified config.xml file.
2) Use the JAXP version as defined in that config.xml file.
configure(File f, int i)
configure(String s, int i)
configure(URL url, int i)
1) Load the configuration values from the specified config.xml file.
2) Use the JAXP version passed as parameter. The allowed parameters are: Configure.JAXP_12, Configure.JAXP_13

You need to call this method only once during the lifetime of your JVM session, as all JAXPTransformer instances will ask the requested configuration attributes from this class.

The example below will configure XMLMill using the default config.xml file defined in the com/xmlmill/conf directory in the xmlmill.jar file.

[001] Configurator.configure();

The next example configures XMLMill using the default config.xml file defined in the com/xmlmill/conf directory in the xmlmill.jar file but telling XMLMill the underlying xml-parser xsl-transformer used is JAXP 1.3 compliant.

[001] Configurator.configure(Configurator.JAXP_13);

The last example configures XMLMill using an external config.xml file and telling XMLMill the underlying xml-parser xsl-transformer used is JAXP 1.3 compliant.

[001] Configurator.configure("file:/C:/Data/XMLMill/TestDirectory/config/config.x
      ml", 
      Configurator.JAXP_13);

Package: com.xmlmill.exception

This package contains all Exception classes used by XMLMill. Following image gives an overview of the classes:

images/exceptions.gif
Select to enlarge

  • For a detailed description of each class please visit the Javadoc API contained in the docs/apidocs directory contained in the download.

Example: TestAppl

The following class defines the xml file and xsl file as File objects and the JAXPTransformer instance generates the .pdf document.

  • Check the XMLMill and DOM chapter to know how to pass a XML Document and/or XSL Document to a JAXPTransformer instance.
  • Check the samples/appl/ directory for more examples regarding how to implement this class with different logging implementations.
[001] 
[002] package com.xmlmilltest;
[003] 
[004] import com.xmlmill.*; 
[005] import com.xmlmill.log.FileLogger; 
[006] import com.xmlmill.config.Configurator;
[007] 
[008] public class testAppl extends Object
[009] {
[010] 
[011]   public static void main(String[] args)
[012]   {
[013]     JAXPTransformer transformer;
[014]     JAXPErrorHandler ehandler;
[015]     FileLogger logger = null;  
[016]     
[017]     try {
[018]     
[019]       ////////////////////////////////////////////////////
[020]       // DEFINE FIRST THE LOGGER INSTANCE TO USE        //
[021]       // HERE DEFAULT com.xmlmill.log.FileLogger        //
[022]       // (you can use any class which implements the    //
[023]       // org.apache.commons.logging.Log interface)      //
[024]       ////////////////////////////////////////////////////
[025] 
[026]       // Use the default FileLogger class
[027]       logger = new FileLogger("xmlmill");  
[028] 
[029]       // Set logfile  
[030]       logger.setFileName("file:/C:/xmlmill3.00/testtransform.txt", false); 
            
[032]       
[033]       // Set the loglevel  
[034]       logger.setLevel("INFO");
[035] 
[036]       // Pass the logger to the XMLMill Configurator, so XMLMill can use 
            it.
[038]       Configurator.setLogger(logger);  
[039]     
[040]       //////////////////////////////////////////////
[041]       // INITIALIZE THE CONFIGURATOR              //
[042]       //////////////////////////////////////////////    
[043]          
[044]       // Define a configurator (optional)
[045]       Configurator.configure();  
[046]     
[047]       //////////////////////////////////////////////
[048]       // CONTINUE                                 //
[049]       //////////////////////////////////////////////      
[050]     
[051]       
[052]       // Define the xml(mill) file to transform  
[053]       File xmlfile = new 
            File("C:\\XMLMill\\samples\\xmlxsl\\phonelist.xml"); 
[055]       
[056]       // Define a XSL file (optional)
[057]       File xslfile = new 
            File("C:\\XMLMill\\samples\\xmlxsl\\phonelist.xsl"); )      
[059]    
[060]       // Define an errorhandler(optional) 
[061]       ehandler = new JAXPErrorHandler(JAXPErrorHandler.ABORT_ON_ERROR );
[062]                                
[063]       // Define a tranform object 
[064]       JAXPTransformer transform = new JAXPTransformer();
[065]  
[066]       // Set the xml file   
[067]       transform.setXMLDocument(xmlfile); 
[068]   
[069]       // Set the xsl file 
[070]       transform.setXSLDocument(xslfile); 
[071]  
[072]       // Define where images and other resources resides on the server 
[073]       transform.setBaseURL(xslfile);
[074]   
[075]       // Set the errorhandler      
[076]       transform.setErrorHandler(ehandler);
[077]         
[078]       // ... and transform the object to a pdf file  
[079]       transform .transform(); 
[080]       System.out.println("-- Done --");        
[081]       
[082]   } catch (Throwable e) {
[083]     System.out.println(e.toString());
[084]   } finally {  
[085]     // Close the logger instance
[086]     logger.finalize();
[087]     
[088]     // Null out instances
[089]     transform = null;
[090]     logger    = null;
[091]     System.out.println("-- Done --");    
[092]   }  
[093] 
[094] }              
[095]         

1

Be sure to import the com.xmlmill package and the com.xmlmill.Configurator package.

2

Use the default com.xmlmill.log.FileLogger class.

3

Define where to send the log messages to.

4

Define the log-level.

5

Pass the logger to the XMLMill Configurator, so XMLMill can use it.

6

Defines the configurator to use. In case you do not add a parameter that represents an external configuration file, the default internal configuration file will be used.

7

Define a file object referencing the xml file that needs to be converted to a PDF file.

8

Define a file object referencing the xsl file that will perform the transformation. This is optional if the xml file contains a reference to a xsl file with the <?xml-stylesheet> tag.

9

Define an errorhandler that will handle all warnings, errors, fatalErrors.

10

Define a transform object.

11

Define the xmlfile to be processed.

12

Define the xslfile to be used.

13

Define where images and other resources resides on the server.

14

Set the errorhandler.

15

Do the transformation.

16

Dereference any variables.

The result will be written in a file defined by the file attribute in the <ml:document> tag. You can override this behavior by using the setOutput(java.io.OutputStream) method, allowing you to send the data to a stream or to another subsystem.

Copyright © 2001 - 2012. All rights reserved. XMLMill and XMLMill logo are trademarks of Pecunia Data Systems, bvba.
Powered by Apache CocoonPowered by XMLMill