2006 IR Open Discussion Posted August 18, 2006 Share Posted August 18, 2006 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 More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now