Re: AttributeMap (was Re: Announcement: SAX 1998-01-12 Draft)

James Clark (jjc@jclark.com)
Thu, 15 Jan 1998 09:24:56 +0700


Matthew Gertner wrote:
>
> James Clark wrote:
>
> >AttributeMap seems way too complicated.
> >
> >I don't think using Enumeration to get all the attributes is a good
> >idea. JDK 1.2 replaces Enumeration by Iterator. The method names in
> >Enumeration are a real disaster in the context of XML: nextElement
> >returns the name of the next attribute! This is not going to be an
> >efficient way to get at all the attributes (which is a common
> >application need). To get at all the attributes, I have first to create
> >an Enumeration (an unnecessary allocation). Then for each attribute
> >name: I have to make two non-final method calls (nextElement and
> >hasMoreElements); I then have a cast (which must be checked) from Object
> >to String; I then have to look the attribute up using getValue. Compare
> >this to the simple interface I suggested:
> >
> >void startElement(String elementName, String[] attributeNames, String[]
> >attributeValues, int nAttributes)
>
> I agree that the AttributeMap is too complicated. On the other hand, your
> alternate proposal seems questionable. Passing three parameters to the event
> handler may be simple, but this eliminates any abstraction, which makes it
> hard to extend the interface cleanly.

If SAX is supposed to be abstract and extensible, then it needs a
substantial rework. Something like this would be much more extensible:

interface DocumentHandler {
void startElement(StartElementEvent event);
void endElement(EndElementEvent event);
void characters(CharactersEvent event);
//...
}

Simplicity was the main design goal of SAX.

Why do we get abstraction and extensibility for attributes but for
nothing else?

> Also, this makes iteration easy but
> finding attributes by name very hard.
>
> An AttributeMap interface should be used, but:
>
> 1) It should provide a standard iterator interface (this is the only
> reasonable way to iterate over a map).

This has all the inefficiencies that I listed for Enumeration.
Requiring an object to be allocated on each start-tag is really not a
good idea (it makes a measurable difference to performance in Java).

Something like this:

interface AttributeList {
int length(); // or maybe size
String getValue(int i); // or maybe valueAt
String getName(int i); // or maybe nameAt
String get(String name);
}

would be significantly more efficient.

At the very least provide an isEmpty() so that I don't have to do the
allocation in the common case there are no attributes.

James