<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META NAME="Generator" CONTENT="MS Exchange Server version 5.5.2650.12">
<TITLE>RE: [jdom-interest] Partial Tree building/instantiation --- XPathFilter</TITLE>
</HEAD>
<BODY>
<BR>

<P><FONT SIZE=2>I have run into this problem as well.&nbsp; I have experimented with one</FONT>
<BR><FONT SIZE=2>approach that works and would like to know what others think of it.</FONT>
</P>

<P><FONT SIZE=2>By the way, I looked at XSLT for a bit, and it appeared to me</FONT>
<BR><FONT SIZE=2>that that the XSLT processor wanted to load the whole document</FONT>
<BR><FONT SIZE=2>into memory first.&nbsp; Saxon has a Preview mode to get around this</FONT>
<BR><FONT SIZE=2>but I didn't research that very far since I would have had to</FONT>
<BR><FONT SIZE=2>do two passes on everything before it was in JDOM where I wanted</FONT>
<BR><FONT SIZE=2>it.</FONT>
</P>
<BR>

<P><FONT SIZE=2>My solution is as follows:</FONT>
</P>

<P><FONT SIZE=2>Add a setHandler() method to a copy of org.jdom.input.SAXBuilder</FONT>
<BR><FONT SIZE=2>to which an element name and a handler class is passed.</FONT>
</P>

<P><FONT SIZE=2>&nbsp;&nbsp;&nbsp; private HashMap handledElements = new HashMap();</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp; public void setHandler(String elementName, ElementHandler handler) {</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; handledElements.put(elementName, handler);</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp; }</FONT>
</P>

<P><FONT SIZE=2>Modify SAXHandler.endElement() (still inside SAXBuilder) so that</FONT>
<BR><FONT SIZE=2>it calls the handler if this is a registered element.&nbsp; Upon return</FONT>
<BR><FONT SIZE=2>from the handler, the element content is removed from the tree.</FONT>
</P>

<P><FONT SIZE=2>The end usage ends up looking something like this:</FONT>
</P>

<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT SIZE=2>...</FONT>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT SIZE=2>MyElementHandler myhandler = new MyElementHandler();</FONT>
</P>

<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT SIZE=2>reader.setHandler(&quot;transferBatch&quot;, myhandler);</FONT>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT SIZE=2>reader.setHandler(&quot;phoneCall&quot;, myhandler);</FONT>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT SIZE=2>try {</FONT>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT SIZE=2>reader.build(srcXmlFilename);</FONT>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT SIZE=2>}</FONT>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT SIZE=2>...</FONT>
</P>

<P><FONT SIZE=2>You can have as many handlers as you want, and, anything you handle </FONT>
<BR><FONT SIZE=2>is discarded after it's handler is called.</FONT>
</P>

<P><FONT SIZE=2>The XPathFilter proposal would be very nice, since</FONT>
<BR><FONT SIZE=2>the above solution only registers explicit element names.</FONT>
</P>

<P><FONT SIZE=2>I wanted to extend SAXBuilder, but I could not see how to do this. </FONT>
<BR><FONT SIZE=2>I see from other posts that XMLFilter may help.&nbsp; I will look at that</FONT>
<BR><FONT SIZE=2>and I welcome more advice in this area.</FONT>
</P>

<P><FONT SIZE=2>I can't see how to avoid needing access to the JDOM Element</FONT>
<BR><FONT SIZE=2>stack (named &quot;stack&quot;) inside the SAXHandler in SAXBuilder.&nbsp; That's</FONT>
<BR><FONT SIZE=2>how I pass the JDOM Element to the handler.&nbsp; Perhaps a small change</FONT>
<BR><FONT SIZE=2>to SAXBuilder would expose a safe interface to that stack and then</FONT>
<BR><FONT SIZE=2>a subclass of SAXBuilder with an XMLFilter might be a clean solution?</FONT>
</P>
<BR>

<P><FONT SIZE=2>Regards,</FONT>
</P>

<P><FONT SIZE=2>Adam Simantel</FONT>
<BR><FONT SIZE=2>Adam.Simantel@merant.com</FONT>
</P>
<BR>
<BR>

<P><FONT SIZE=2>-----Original Message-----</FONT>
<BR><FONT SIZE=2>From: Steven Gould [<A HREF="mailto:steven.gould@cgiusa.com">mailto:steven.gould@cgiusa.com</A>]</FONT>
<BR><FONT SIZE=2>Sent: Monday, April 02, 2001 2:14 PM</FONT>
<BR><FONT SIZE=2>To: jdom-interest@jdom.org</FONT>
<BR><FONT SIZE=2>Subject: Re: [jdom-interest] Partial Tree building/instantiation ---</FONT>
<BR><FONT SIZE=2>XPathFilter</FONT>
</P>
<BR>

<P><FONT SIZE=2>Jakob,</FONT>
</P>

<P><FONT SIZE=2>Could you use XSLT to break the file up into smaller, more manageable</FONT>
<BR><FONT SIZE=2>documents? Then use JDOM to manipulate/process each of these smaller</FONT>
<BR><FONT SIZE=2>documents.</FONT>
</P>

<P><FONT SIZE=2>Steve</FONT>
</P>

<P><FONT SIZE=2>---</FONT>
</P>

<P><FONT SIZE=2>Jakob Jenkov wrote:</FONT>
</P>

<P><FONT SIZE=2>&gt; Hi There. I'm currently working on a long, long :-) project in which</FONT>
<BR><FONT SIZE=2>&gt; we parse through some quite long files. We have tried converting these</FONT>
<BR><FONT SIZE=2>&gt; files to XML for easier/standard parsing but each file will then be of</FONT>
<BR><FONT SIZE=2>&gt; a size of about 16-30+ MB each. I don't even dare think about how much</FONT>
<BR><FONT SIZE=2>&gt; memory such a JDOM tree would take! And the plans for lazy evaluation</FONT>
<BR><FONT SIZE=2>&gt; won't help, since we are visiting every node in the tree, thus</FONT>
<BR><FONT SIZE=2>&gt; instantiating all objects anyway. Parsing the trees solely using SAX</FONT>
<BR><FONT SIZE=2>&gt; is not developer-friendly enough. What I have in mind is some kind of</FONT>
<BR><FONT SIZE=2>&gt; a XPath filter, allowing you to build JDOM trees from sub trees from</FONT>
<BR><FONT SIZE=2>&gt; the data, and dipose these trees when I don't longer need that tree.</FONT>
<BR><FONT SIZE=2>&gt; Let me give an example: We parse phone call records in files that</FONT>
<BR><FONT SIZE=2>&gt; sometimes can contain thousands and thousands of records. In XML</FONT>
<BR><FONT SIZE=2>&gt; format these files and records would look something like</FONT>
<BR><FONT SIZE=2>&gt; this: &lt;transferBatch&gt;&nbsp;&nbsp;&nbsp; &lt;phoneCall&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;details&gt;bla.bla.bla., sub</FONT>
<BR><FONT SIZE=2>&gt; records etc.&lt;/details&gt;&nbsp;&nbsp;&nbsp; &lt;/phoneCall&gt;&nbsp;&nbsp;&nbsp; &lt;phoneCall&gt;</FONT>
<BR><FONT SIZE=2>&gt; &lt;details&gt;bla.bla.bla., sub records etc.&lt;/details&gt;&nbsp;&nbsp;&nbsp; &lt;/phoneCall&gt;</FONT>
<BR><FONT SIZE=2>&gt; &lt;phoneCall&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;details&gt;bla.bla.bla., sub records</FONT>
<BR><FONT SIZE=2>&gt; etc.&lt;/details&gt;&nbsp;&nbsp;&nbsp; &lt;/phoneCall&gt;&nbsp;&nbsp;&nbsp; ...&nbsp;&nbsp;&nbsp; ...</FONT>
<BR><FONT SIZE=2>&gt; ...&lt;/transferBatch&gt;&nbsp;&nbsp; Each &lt;phoneCall&gt; record with all it's sub</FONT>
<BR><FONT SIZE=2>&gt; records can be quite large, and there can be thousands of these</FONT>
<BR><FONT SIZE=2>&gt; &lt;phoneCall&gt; records. I'd like some way to get a JDOM tree for each</FONT>
<BR><FONT SIZE=2>&gt; &lt;phoneCall&gt; record one at a time, and to be able to dispose</FONT>
<BR><FONT SIZE=2>&gt; &lt;phoneCall&gt; JDOM tree before moving on to the next. How will I do</FONT>
<BR><FONT SIZE=2>&gt; that? My Suggestion would be to insert an XPathFilter, that only</FONT>
<BR><FONT SIZE=2>&gt; builds JDOM trees from the records that match the given XPath. In the</FONT>
<BR><FONT SIZE=2>&gt; example above, an XPath of&nbsp;&nbsp;&nbsp; transferBatch::phoneCall&nbsp;&nbsp; would have</FONT>
<BR><FONT SIZE=2>&gt; done the job. Does my complaints/ideas sound completely</FONT>
<BR><FONT SIZE=2>&gt; out-of-this-world? I think there are many out there who will have the</FONT>
<BR><FONT SIZE=2>&gt; same problem, parsing one sub tree at a time, without regard to the</FONT>
<BR><FONT SIZE=2>&gt; others.&nbsp; Regards,Jakob Jenkovjakob@jenkov.com</FONT>
<BR><FONT SIZE=2>_______________________________________________</FONT>
<BR><FONT SIZE=2>To control your jdom-interest membership:</FONT>
<BR><FONT SIZE=2><A HREF="http://lists.denveronline.net/mailman/options/jdom-interest/youraddr@yourhost.com" TARGET="_blank">http://lists.denveronline.net/mailman/options/jdom-interest/youraddr@yourhost.com</A></FONT>
</P>

</BODY>
</HTML>