Jump to content

Is JRXmlDataSource production strength?


toltsch

Recommended Posts

Hi Everyone.

 

I'm using the 1.2.2 version of Jasper Reports.

 

I'm seeing performance issues when using the JRXmlDataSource. I have an input file of about 700K and it takes about 2 secs per page to fill the report. The output of the report is sent to PDF (this is fast and appears to have no issues).

 

I've seen post from 2003 on discussing that files of 2MB and over have had slow response times when using the JRXmlDataSource.

 

I've also seen posts back from the JasperReports Dev team that for better response you have to code a the report using a custom DataSource.

 

Is this the only option for better response time for large XML files?

 

Can anyone point me at a good example of implementing a custom XML DataSource?

 

Also, has anyone come up with a new Xml DataSource which others can use?

 

Any help will be greatly appreciated.

 

Thanks,

 

Tim

Link to comment
Share on other sites

  • Replies 5
  • Created
  • Last Reply

Top Posters In This Topic

I rewrote the JasperReports JRXmlDataSource using Jaxen and I got a 600% increase in performance.

 

Maybe the Jasper Reports team can rewrite their version using Jaxen?

 

Here is the source code for other people struggling with this issue. I'm using Jasper Reports 1.2.2 with Jaxen 1.1

 

/*

* Created on Sep 10, 2006

*

* TODO To change the template for this generated file go to

* Window - Preferences - Java - Code Style - Code Templates

*/

package com.cwi.direct.custom.datasource;

 

import net.sf.jasperreports.engine.JRDataSource;

import net.sf.jasperreports.engine.JRException;

import net.sf.jasperreports.engine.JRField;

import net.sf.jasperreports.engine.util.JRXmlUtils;

 

 

import java.io.File;

import java.util.List;

import java.util.ArrayList;

 

import javax.xml.parsers.DocumentBuilderFactory;

import javax.xml.parsers.DocumentBuilder;

 

import org.apache.commons.beanutils.ConvertUtils;

 

import org.jaxen.JaxenException;

import org.jaxen.XPath;

import org.jaxen.dom.*;

 

import org.w3c.dom.Document;

 

/**

* @author Tim Oltsch (toltsch@commercialware.com)

* @version $Id: CWXmlDataSource.java,v 1.0 2006/09/11 09:00:00 toltsch Exp $

*/

public class CWXmlDataSource implements JRDataSource

{

// the xml document

private org.w3c.dom.Document document;

 

// the XPath select expression that gives the nodes to iterate

private String selectExpression;

 

// the node list

private List nodeList;

 

// the node list length

private int nodeListLength;

 

// the current node

private Object currentNode;

 

// current node index

private int currentNodeIndex = - 1;

 

/**

*

*/

public CWXmlDataSource()

{

}

 

public CWXmlDataSource(Document document, String selectExpression) throws JRException {

this.document = document;

this.selectExpression = selectExpression;

moveFirst();

}

 

public CWXmlDataSource(String uri, String selectExpression) throws JRException {

this(CWXmlDataSource.loadDocumentFromFile(uri), selectExpression);

}

 

public void moveFirst() throws JRException {

if (document == null)

throw new JRException("document cannot be not null");

if (selectExpression == null)

throw new JRException("selectExpression cannot be not null");

 

try {

currentNode = null;

currentNodeIndex = -1;

nodeListLength = 0;

nodeList = getXpathNodeList(document, selectExpression);

nodeListLength = nodeList.size();

} catch (Exception e) {

throw new JRException("XPath selection failed. Expression: "

+ selectExpression, e);

}

}

 

/**

*

*/

public boolean next() throws JRException

{

if(currentNodeIndex == nodeListLength - 1)

return false;

 

currentNode = nodeList.get(++ currentNodeIndex);

return true;

}

 

 

/**

*

*/

public Object getFieldValue(JRField jrField) throws JRException

{

if(currentNode == null)

return null;

 

String expression = jrField.getDescription();

if (expression == null || expression.length() == 0)

return null;

 

Object value = null;

 

Class valueClass = jrField.getValueClass();

 

if(Object.class != valueClass) {

String text = null;

 

try {

text = getXpathStringValue(currentNode,expression);

} catch (Exception e) {

throw new JRException("XPath selection failed. Expression: "

+ expression, e);

}

 

if(text != null) {

if(String.class == valueClass)

value = text;

else

value = ConvertUtils.convert(text.trim(), valueClass);

}

}

 

return value;

}

 

protected static Document loadDocumentFromFile(String file) throws JRException

{

Document doc = null;

 

try

{

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

dbf.setNamespaceAware(true);

DocumentBuilder db = dbf.newDocumentBuilder();

doc = db.parse(new File(file));

}

catch(Exception e)

{

throw new JRException("Input file:"+file+ " was not found.");

}

 

return doc;

}

 

protected List getXpathNodeList(Object doc,String domxpath) throws Exception

{

try

{

XPath xpath = new DOMXPath(domxpath);

Object ro = xpath.evaluate(doc);

if (ro instanceof List)

return (List)xpath.evaluate(doc);

else

{

List results = new ArrayList();

results.add(ro);

return results;

}

}

catch(JaxenException je)

{

throw je;

}

}

 

protected String getXpathStringValue(Object node,String domxpath) throws Exception

{

try

{

XPath xpath = new DOMXPath(domxpath);

String value = xpath.stringValueOf(node);

if (value.length() == 0)

return null;

else

return value;

}

catch(JaxenException je)

{

throw je;

}

}

 

public CWXmlDataSource subDataSource(String selectExpr) throws JRException {

// create a new document from the current node

Document doc = subDocument();

return new CWXmlDataSource(doc, selectExpr);

}

 

public Document subDocument() throws JRException

{

if(currentNode == null)

{

throw new JRException("No node available. Iterate or rewind the data source.");

}

 

// create a new document from the current node

Document doc = JRXmlUtils.createDocument((org.w3c.dom.Node)currentNode);

return doc;

}

 

public CWXmlDataSource dataSource(String selectExpr) throws JRException {

return new CWXmlDataSource(document, selectExpr);

}

}

Link to comment
Share on other sites

  • 9 months later...

The Xalan-specific XPath evaluation code has been extracted from JRXmlDataSource into a separate class which implements a generic XPath interface (JRXPathExecuter). A Jaxen-based implementation of this interface has also been written.

 

A JR property (in jasperreports.properties) is used to specify the XPath executer factory class. By default, the Xalan-based XPath executer is still used (to ensure backward compatibility). To switch to the Jaxen-based XPath executer, set the following property:

Code:

net.sf.jasperreports.xpath.executer.factory=net.sf.jasperreports.engine.util.xml.JaxenXPathExecuterFactory

 

All these changes can be found on JasperReports SVN trunk. If you have any feedback on this, let us know.

 

Regards,

Lucian

Link to comment
Share on other sites

Link to comment
Share on other sites

  • 3 years later...

After setting the below property in default.jasperreports.properties, we are not able to see any data in excel.

net.sf.jasperreports.xpath.executer.factory=net.sf.jasperreports.engine.util.xml.JaxenXPathExecuterFactory
 

But we are getting the data from database and we are passing that data to JRXmlDataSource .

Do we need make changes anywhere else?

Thanks
 

shiva

Link to comment
Share on other sites

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