This manual will explain how to download and install the pp-odf-xslt package, how to create ODF-XSLT templates from within your favourite office applications and how to use the commandline tool to convert those templates to new ODF documents. At the end it will show you how you can use and extend the ODF-XSLT library inside your PHP applications. Developers who want to use ODF-XSLT in their applications will also want to read the API Reference.
To use PHP-ODF-XSLT, you will need the following libraries installed on your system:
Download the odf-xslt package from the download section and extract it somewhere convenient. Then open up a terminal and from the package directory run the following commands:
ODF-XSLT documents are basically just ODF documents where XSLT markup has been insterted in the XML files inside the ODF container. Usually just in content.xml and styles.xml because these two are automatically parsed by the ODFXSLTProcessor. You can generate these XSLT documents directly using your favourite XML tool, or you can generate them from specially marked up ODF documents using your favourite ODF editor, such as OpenOffice.org.
If you unzip an ODF-XSLT file and take a look at the content.xml file, you can see that it's just plain XSLT. If you understand the OpenDocument Format specification and the XSL Transformations specification then you could generate these documents manually or from within another application. Below is an excerpt of a simple ODF-XSLT document.
Instead of creating ODF-XSLT documents manually, you can also use your favourite ODF-compliant Office application to create specially marked-up ODF documents. The ODFXSLTProcesser translates these documents on–the–fly to ODF-XSLT documents which are then processed with the supplied XML data to create the final ODF document.
The basic syntax to create ODF-XSLT documents is simple, but powerfull. You do need a basic understanding of the OpenDocument Format, XSL Transformations and XPath though. The ODF-XSLT syntax lets you insert XSLT tags at specified locations inside your ODF document. The basic syntax is:
With the XPath expression you select one or more XML nodes in your ODF document. The XSLT expression is then insterted into the document at the specified position. The position parameter can be one of before, after, append or replace. An example to clarify this. Suppose that you wish to repeat a certain paragraph, once for each node in the XML file. The paragraph "Repeat me" looks like this in XML:
You can simply add the ODF-XSLT expressions directly in the paragraph:
The XPath expression ".." points to the <text:p> node. Note that you need to disable automatic hyperlinking in your office suite, to prevent it from creating mailto links from the code. The ODFXSLTProcesor cannot read the template syntax if they are broken up by ODF style rules. In XML, the paragraph looks like this:
The two ODF-XSLT expressions say: Add <xslt:for-each select="/foo/bar"> before the <text:p> node, and add </xslt:for-each> after it. When the ODFXSLTProcessor parses it, the XSLT looks like this:
This piece of XSLT can be combined with an XML file to create a new ODF file. Below is a sample XML file and the XML that it will result in:
Because you can add any XSLT tags to any ODF node through XPath, the possibilities are virtually endless. But adding lots of XSLT directly into the document doesn't look very good. The ODFXSLTProcessor recognises two alternative methods. The first method is inserting an ODF text placeholder into the document. In OpenOffice.org Writer you can do that via insert->field->other menu. You can use anything you want as the placeholder text. The placeholder reference should be an XPath expression into the data XML that points to whatever the placeholder should be replaced with. See the screenshot below.
A second way to unclutter your document is to use <text:script> elements to put your ODF-XSLT snippets in. If you use ODF-XSLT as the script language parameter then the ODFXSLTProcessor will strip the script elements after processing the template snippets. Here's a screenshot showing the "Repeat me" example implemented with script elements.
The easiest method by far for simple variable substitution is the placeholder text method explained in section 2.2.1. The XPath expression in the reference field of the placeholder is run from where you currently are in the XML data field. Take for example the following XML data:
When you are doing a row repeat on /foo/bar and you want the placeholder to be replaced with the value of the baz element, then the reference field of the placeholder should simply be baz.
Repeating table rows is pretty simple. Create a table in your ODF document and put an ODF-XSLT script element in one of the cells of the row you want to repeat. If you want to repeat over the /foo/bar elements from the previous example, then the code for the script element should be:
Table column repeat is slightly harder than table row repeat. That's because of the way that tables are built in ODF. Tables in ODF are very similar to tables in HTML: you have rows containing cells, with column definitions separately in the table header. For example:
If you want to repeat column B for each /foo/bar from the example data XML then you need to repeat the second cell in each row and you need to repeat the second table-column. To do so, create a script element in the top cell of the second column and insert the following code. The first two rules repeat the second table-column element. The second two rules repeat the second cell element of each row.
Image replacement is most easily done from within the image itself. Insert an image into the document and format it the way you want it. Then place the ODF-XSLT code into the images "alternative text" attribute. For example, if the data XML contains the full path to the image you want to use in /foo/image-path, then put the following code into the alternative text field:
This will replace the image xlink:href attribute of the image with the value of /foo/image-path from the data XML. The ODFXSLTProcessor will check all the image xlink:href paths and make sure that the actual images are included in the ODF container.
The odf-xslt package comes with a commandine tool called odfxsltproc that allows you to convert XML data to ODF documents easily. It processed XML data from STDIN and outputs to a specified location. Usage:
Example usage when converting an XML file to ODF:
Using the ODFXSLTProcessor in your own PHP application is very easy. Simply instanciate a new ODFXSLTProcessor, load a stylesheet and call transform_to_file() or transform_to_memory() with the XML data as a PHP DOMDocument. The example below should explain itself.
For a complete overview of the ODFXSLTProcessor you should read the ODF-XSLT API Documentation.
If you want to extend the functionality of the ODFXSLTProcessor then you do not need to subclass it. The processor allows you to register custom preprocessor and postprocessor functions. The preprocessor is executed after the XSLT tags have been inserted but before the XML data is parsed. The postprocessor is called after the XML data has been parsed. Pre- and postprocessors are executed in the order they are registered and are executed once for each ODF XML file specified in the $container_files class attribute. By default those are the content.xml and styles.xml files.
The example below shows a post-processor that removes all empty paragraphs.