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.

 

Pavel

 

 

 

 

By: Teodor Danciu - teodord

RE: xml reporting

2003-03-26 06:57

 

Hi,

 

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.

Teodor

 

 

 

 

 

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

Hi-

 

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 {

rootIndex++;

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...