For this last posting on XML
Publisher I thought I'd take a look at how reports are deployed
into production. The approach I've used so far - build a report
template using the XML Publisher Desktop product, then preview
it as a PDF - is obviously the way that you'd develop and test
reports, rather than roll them out, so I thought I'd take a look
at how you can distribute the reports you've created.
The XML Publisher 5.5 download
comes with two products; XML Publisher Desktop, the add-in to
Microsoft Word that allows you to add XML Publisher data fields
and report layout commands to an RTF document, and XML Publisher
Server, a product that I hadn't taken a look at yet but that
obviously looked promising as a delivery mechanism for reports
I'd created using the Desktop product. The download also came
with a number of demos for both Desktop and Server, and so I
thought the best way of seeing the Server product in action was
to run through the demos.
After installing Oracle
Containers for Java 10.1.2, the Sun Java JDK 1.5.02 for Windows
and installing them both, the next step was to install XML
Publisher Server - or not as the case may be. Looking through
the instructions for the server product, and the demos, it turns
out that what you do is actually just copy the application
you've created using the XML Publisher libraries, as an EAR or a
WAR file, to the /applications directory of your application
server, and then when you restart the application server the
archive file should auto-deploy, containing with it the
libraries to implement the XML Publisher Server functionality.
There isn't a server product to install as such, the server is
actually implemented as a servlet that runs within (in my
instance) OC4J 10.1.2 - Apache Tomcat is also supported but it
doesn't come with the XML Parser and JDBC libraries that you
need to get XML Publisher working, I tried this first but
couldn't get the demo applications working.
The most interesting demo that
comes with XML Publisher Server is the "Online Reporting" demo.
This demo gives you a web site where you can upload XML
Publisher reports, and then run them on demand - as such it's a
good pointer to how you might end up deploying XMLP reports in
real life. When you get the application up and running, you get
presented with a page looking like this:

Note the
distinction between the report - which is an XML file - and the
template - which is something separate. From reading through the
documentation, it turns out that an XML Publisher "report
definition" is actually an XML file with the extension ".xdo" -
this is analogous to the ".rdf" or ".jsp" report definition file
for Oracle Reports. This XML file actually references within it
either the XML or SQL data source, and the RTF template file
that defines how the report is layed out. Here's a quick excerpt
from the docs:
"XDO
Format :
XML publisher report definition follows an
XML-based format and is named with the “.xdo” suffix. The
definition specifies where and how data should be retrieved,
and which RTF layout templates are associated with the report.
A report is divided into three major sections: data sets,
report parameters and layout. The following example is a
simple report definition (\samples\onlinereport\dbtest\EmpDept.xdo)
that illustrates how a report can be created:
<?xml version="1.0"
encoding="UTF-8"?>
<report xmlns="http://xmlns.oracle.com/xdo/servlet" xmlns:xdo="http://xmlns.oracle.com/xdo/servlet">
<dataSets>
<dataSet name="xml-data" >
<sqlQuery dataSourceRef="demo">
<sql>
SELECT E.EMPNO, E.ENAME, E.JOB, E.SAL, D.DNAME
FROM EMP E, DEPT D
WHERE E.DEPTNO = D.DEPTNO
{$if ${jobtitle}='*' $}
{$else $}
AND E.JOB = :jobtitle
{$endif $}
{$if ${dept}='*' $}
{$else $}
AND E.DEPTNO = :dept
{$endif $}
AND E.SAL > :lowsal
ORDER BY ENAME
</sql>
<input name="jobtitle" value="${jobtitle}" dataType="xdo:STRING"/>
<input name="dept" value="${dept}" dataType="xdo:INTEGER"/>
<input name="lowsal" value="${lowsal}" dataType="xdo:INTEGER"/>
<output name="result" dataType="xdo:XML"/>
</sqlQuery>
</dataSet>
<dataSet name="job-list" >
<sqlQuery dataSourceRef="ipg">
<sql>
SELECT DISTINCT(JOB) FROM EMP ORDER BY JOB
</sql>
<output name="result" dataType="xdo:MAP"/>
</sqlQuery>
</dataSet>
<dataSet name="dept-list" >
<sqlQuery dataSourceRef="ipg">
<sql>
{$if ${jobtitle}='*' $}
SELECT DISTINCT(D.DNAME), D.DEPTNO FROM DEPT D ORDER
BY DNAME
{$else $}
SELECT DISTINCT(D.DNAME), D.DEPTNO FROM DEPT D, EMP
E WHERE D.DEPTNO = E.DEPTNO AND E.JOB = :jobtitle ORDER BY
DNAME
{$endif $}
</sql>
<input name="jobtitle" value="${jobtitle}" dataType="xdo:STRING"/>
<output name="result" dataType="xdo:MAP"/>
</sqlQuery>
</dataSet>
</dataSets>
<layOut>
<renderer type="uix" title="Sample Report" columns="3"/>
<templates>
<template name="Sample" type="rtf" url="sample.rtf"
isDefault="true"/>
<template name="Unicode" type="rtf" url="unicode2.rtf"/>
</templates>
<data bind="${xml-data.result}"/>
</layOut>
<reportParameters>
<reportParameter name="jobtitle" defaultValue="MANAGER"
submitOnChange="true">
<select label="Job Title:" all="true">
<item label="${job-list.result.JOB}" value="${job-list.result.JOB}"/>
</select>
</reportParameter>
<reportParameter name="dept" defaultValue="*"
submitOnChange="false">
<select label="Department:" all="true">
<item label="${dept-list.result.DNAME}" value="${dept-list.result.DEPTNO}"/>
</select>
</reportParameter>
<reportParameter name="lowsal" defaultValue="0">
<input label="Salary Greater Than:"/>
</reportParameter>
</reportParameters>
</report>
The Data sets
section defines data sets used either for parameter LOVs or
for the report. There are five types of data sets supported:
SQL, Oracle PL/SQL, HTTP, Web services (document/literal
only), and Oracle data templates, corresponding to sqlQuery,
plsqlQuery, http, webservice and advancedQuery. Each data set
must have a unique name inside the report, and optionally can
have multiple input parameters and output parameters. Also
note that the data source a data set uses must already be
defined in the configuration file.
The XDO format supports an object model that is similar to the
Javascript DOM model; that is, an object can be referenced
directly by its name using the format ${VARIABLE_NAME}. For
example, for an output variable with the name result inside a
data set with the name xml-data, its value is referenced as
${xml-data.result}. The object types supported are: xdo:STRING,
xdo:STRINGARRAY, xdo:INTEGER, xdo:XML, xdo:MAP.
IF-ELSE IF-ELSE-ENDIF logic is supported in the format
demonstrated in the above example, and the test condition must
be either equal(=) or not-equal(!=). Note the * in the test
condition means all for the tested object.
Report parameters are dynamic values that a report is
dependent upon. Usually end users decide specific values for
those report parameters, if any, and then a report document
can be generated with data based on the parameter values. A
report parameter is either an input field (input) or an LOV
(select). For the LOV type parameter, if all attribute is set
to be true, an all option is added automatically to the LOV.
As stated above, the value of a report parameter can be
referenced as ${PARAMETER_NAME}.
Report templates must be uploaded through the application
administration page and defined inside the layOut section of a
report definition. The value of name attribute is the display
name and the value of url attribute must be the same as the
uploaded template file name."
Interesting. So the way this
works is that the RTF file you generate using XML Publisher
Desktop, together with the XML document if your report is based
on XML data as opposed to an SQL query, is accompanied in real
life by an XML .xdo file that ties it all together. I'm not sure
how you would create this .xdo file at the moment - I don't
think XML Publisher Desktop creates it for you, although I
expect it creates one "on the fly" when you preview a report, so
I guess with this version you have to create it yourself.