[
Lists Home |
Date Index |
Thread Index
]
Arjun Ray wrote:
> Which brings me to my long-standing beef with SAX: state maintenance. A
> lot of the time, what we call state dependence is more accurately context
> dependence. In SAX, if you split up the event handling in the app among
> various classes, you have to mess with setHandler() calls explicitly and
> track the stack at the same time to get this right. This is a pain.
hi,
i agree completely and seen it before but i have reached different conclusion:
use pull parser API :-)
> In search of a more "natural" idiom, I've been experimenting with a pure
> push API which supports stack-based delivery of events. It's built around
> two mutually dependent interfaces that the consumer will have to implement
> which look like this (many details omitted):
this looks very similar to what all applications are doing that has to convert
SAX event callbacks into objects - for example deserializers in AXIS ...
> Cheesy example:
>
> public class HtmlTable implements Element, Content {
> ...
> Element newChild( ) {
> return (Element) new HtmlTr( ) ; // sexier constructors possible
> }
how do you know that every child of table has to be tr?
>
> Content endChild( Content child ) {
> if ( child instanceof HtmlTr ) {
> // etc
> }
> return this ;
> }
> }
>
> public class HtmlTr implements Element, Content {
> void gi( String name ) {
> if ( ! "tr".equals( name ) )
> throw ScreamAndDieException ;
> }
> Content content( ) {
> return (Content) this ;
> }
> // etc
> }
>
> A lot of this is boilerplate code that can also be "hoisted". For deep or
> deeply recursive structures in the XML, this works very well, I've found.
i think it can be done much easier with xml pull parser without any
special support, for example to create HtmlTable from XML input:
XmlPullParser pp = ...
HtmlTable table = HtmlTable.unmarshal(pp);
and here is implementation:
public class HtmlTable {
Vector rows = new Vector();
public statoc HtmlTable unmarshal(XmlPullParser pp) {
if(pp.getEventType() != pp.START_TAG || !"table".equals(pp.getName())
thow new ValidationExceptiopn("expected start tag for HTML table"+pp.getpositionDesacripton());
HtmlTable table = new HtmlTable();
//parse table containig of <tr>s
while(pp.nextTag() == pp.START_TAG) {
if("tr".equals(pp.getName())) {
HtmlTr tr = HtmlTr.umarshal(pp);
table.rows.addElement(tr);
} else {
thow new ValidationExceptiopn(
"expected start tag for HTML tr inside table and not start tag"
+pp.getName()pp.getpositionDesacripton());//ScreamAndDieException ;
}
}
if(!"table".equals(pp.getName())
thow new ValidationExceptiopn("expected end tag for HTML table"+pp.getpositionDesacripton());
}
return table;
}
public class HtmlTtr {
Vector content = new Vector();
public statoc HtmlTr unmarshal(XmlPullParser pp) {
if(pp.getEventType() != pp.START_TAG || !"tr".equals(pp.getName()) //checking pre-condition
thow new ValidationExceptiopn("expected start tag for HTML table"+pp.getpositionDesacripton());
HtmlTtr tr = new HtmlTr();
//parse content of <tr>s
// usnig nextTag() and nextText() and delegating work to sub-classes ...
return tr;
}
}
alek
|