Jump to content

Recommended Posts

By: Pavel Hlavnicka - pavel_hlavnicka

xml reporting

2003-03-26 02:54

Hi all,


has anybody got some experience with reporing the XML data source using JasperReports? As I understand, I'd need some XML JDBC driver to achive this. Is it right?


I searched the net a bit, but no success yet. I'm sorry, if I'm asking something trivial.







By: Teodor Danciu - teodord

RE: xml reporting

2003-03-26 06:57




There is no XML JDBC driver needed.

But you still have to parse yourself this XML

and wrap it into a JRDataSource object that

you can pass to the engine to fill a report.


See some documentation about parsing XML files

in Java.


I hope this helps.







By: Pavel Hlavnicka - pavel_hlavnicka

RE: xml reporting

2003-03-26 08:48

Great, I'm happy with this. I supposed, that JRDataSource is just wrapper for JDBC connections.


XML is my domain, I can help myslef IMHO :). Thanks a lot.





By: Eric Everman - eeverman

RE: xml reporting

2003-03-26 09:13



I have a handy wrapper class for reading DOM models as JRDataSources. It allows nested node access and allows subreport datasources to be created from the main report as a subtree of the datasource.


Code below,


Eric Everman




import dori.jasper.engine.JRDataSource;

import dori.jasper.engine.JRException;

import dori.jasper.engine.JRField;

import org.w3c.dom.*;

import java.util.StringTokenizer;



* @author eric


* An implementation of JRDataSource that takes one or more DOM Elements

* as the data source. Using the single Element constructor is equivalent

* to a single row JDBC recordset.


* Field names are resolved by finding the *first* matching child node within

* the current Element (refered to as the 'relativeRoot'). Reaching nested

* values is possible by using a dot notation in the field description. For

* instance, assume an XML structure like this (using [] for <>):


* [ReportData] < -- This node is the relativeRoot

* [Contact]

* [FristName]Bob[/FirstName]

* [/Contact]

* [/ReportData]


* FirstName could be accessed with a Jasper report field declariation like this:


* [field name=C_FirstName" class="java.lang.String]

* [fieldDescription]Contact.FirstName[/fieldDescription]

* [/field]


* In this example, the 'name' attribute could be anything, while the

* fieldDescription contain the actual 'path' to the value, relative to the root

* element. The fieldDescription trick is needed because dots are invalid

* characters for field names. Direct children of the relative root do not need

* this trick, so only the name is required.


public class DOMElementDataSource implements JRDataSource {



Element [] relativeRoots; //Array of school document roots

int rootIndex = -1; //Index of the current elem in roots



public DOMElementDataSource(Element [] relativeRoots) {

this.relativeRoots = relativeRoots;



public DOMElementDataSource(Element relativeRoot) {

this.relativeRoots = new Element [] { relativeRoot };





* Builds a new DOMElementDataSource using a child node of the current

* relativeRoot (a child node). If the passed child node name is null

* or empty, a source is created using the same instance of the

* relative root. If the specified child is not found, an error is thrown.


* This method is typically used in subreport expressions to create a 'child'

* datasource for the subreport, using a subtree of the current datasource.


public DOMElementDataSource buildSourceFromNode(String nodeName) throws Exception {

if (nodeName == null || nodeName.equals("")) {

return new DOMElementDataSource(getCurrentRoot());

} else {

Element e = findFirstElementByExpression(getCurrentRoot(), nodeName);


if (e != null) {

return new DOMElementDataSource(e);

} else {

throw new Exception(

"The specified child node '" +

nodeName +

"' could not be found to create a new data source.");






* Get the field value based on the field description (if not empty)

* of based on the field name. If description is used, dot separated

* nexted nodes are accepted.


public Object getFieldValue(JRField field) throws JRException {


String key = field.getDescription();

Element el = null;


if (key != null && !key.equals("")) {

el = findFirstElementByExpression(relativeRoots[rootIndex], key);

} else {

key = field.getName();

el = findFirstElement(relativeRoots[rootIndex], key);




Node out = el.getFirstChild();


if (out != null) {


if (out.getNodeType() == Node.TEXT_NODE) {

return out.getNodeValue();

} else {

return "No text associated with this node";



} else {

return "";






* Increments rootIndex and return true if less then roots length


public boolean next() throws JRException {


return (rootIndex < relativeRoots.length);





public Element getCurrentRoot() {

return relativeRoots[rootIndex];



static Element findFirstElementByExpression(Element parent, String name) throws JRException {


if (name.indexOf('.') > -1) {

//name is an expression with '.' separators


StringTokenizer st = new StringTokenizer(name, ".");

String currentTk = null;

Element currentEl = parent;


try {

while (st.hasMoreTokens()) {

currentTk = st.nextToken();

currentEl = findFirstElement(currentEl, currentTk);


} catch (JRException e) {

throw new JRException(

"The DOM node '" + currentTk +

"' was not found in the expression '" + name + "'");



return currentEl;


} else {

//No dot separators

return findFirstElement(parent, name);





static Element findFirstElement(Element parent, String name) throws JRException {

NodeList list = parent.getElementsByTagName(name);

if (list.getLength() > 0) {

return (Element)(list.item(0));

} else {

throw new JRException("The DOM node '" + name + "' was not found.");





Link to comment
Share on other sites

  • Replies 0
  • Created
  • Last Reply

Top Posters In This Topic

Popular Days

Top Posters In This Topic

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Create New...