[
Lists Home |
Date Index |
Thread Index
]
Michael Brennan wrote:
>As part of that, I have a very small, simple library for outputting XML
>to SAX event handlers. The goal was to come up with a simple, compact,
>and readable notation for creating SAX-based
>XML output with a reasonable amount of built-in error checking.
>
hi,
as i am writing a review of different XML output libraries for Java it
is interesting to hear about you work and i am also author YAXOL (yet
another XML output library) called XmlSerializer so naturally i wanted
to compare it with Swan.
there is however one aspect that i could hardly understand: am i right
that Swan builds in memory a node tree (ContainerResult with recursive
children list)? that tree is then flushed when last child is written for
parent but that means that for deeply nested trees all earlier children
of depth lower than current one will be in memory? if i am right then i
am curious why would you do that (did you consider of XML streaming or
assumed small XML docs and DOM like memory requirements)?
>I tried
>to come up with an API that comes as close as possible to the
>simplicity, compactness, and readability of the markup being produced.
>
in XmlSerialzier we had the same goals so it is even more interesting to
compare results.
here some of my observations:
* both APIs supports full XML infoset and XML namespaces but by reading
Swan API and code i could not figure out if Swan will auto declare
prefix for unknown namespace (XmlSerializer will generate xmlns:prefix
declaration thus leaving user from need to deal with namespaces prefixes
but still allows to setPrefix() manually if desired so)
* Swan depends on SAX but XmlSerializer is completely independent
interface that can be used without SAX (though XmlSerializer could be
made to work with SAX easily)
* XmlSerializer API is interface based but Swan is POJO and that makes
harder to write interceptors (for example to add aspects to XML output
code and that is quite common need) or create alternative implementation
of API (if one would like to enhance Swan and not just use different
LexicalHandler)
* XmlSerializer is very simple - just one interface and Swan has 11 classes
* XmlSerializer is very small - interface + implementation (MXP1) is
10K, Swan is 40K
* XmlSerializer protects against mismatched endTag() calls by requiring
endTag() to declare what is its corresponding startTag() and that pays
off when writing a lot of XML in large applications. it seems that Swan
allows only end() call that will close any current context and that can
easily lead to hard to find errors ...
>There is obvious limits to how far you can with this with a Java API
>(without resorting to a template language), but I thought I'd see what I
>could come up with. Here is what I came up with:
>
>Consider the following XML snippet:
>
> <department>
> <employee id="500">
> <firstName>Kilgore</firstName>
> <lastName>Trout</lastName>
> </employee>
> </department>
>
>
>The code to produce this directly using SAX would be quite ugly and
>verbose, in spite of the simplicity of the markup being produced.
>
agreed.
>Alternatively, we could emit each element as it is completed, and could
>use an indentation style that emulates (somewhat) the XML structure we
>wish to generate:
>
> ResultFactory factory = new ResultFactory();
> DocumentResult result =
> factory.newDocumentResult(new StreamResult(System.out));
>
> result.element("department")
> .element("employee").attribute("id", "500").end()
> .element("firstName")
> .text("Kilgore")
> .end()
> .element("lastName")
> .text("Trout")
> .end();
>
> // bail out here and output the remaining result tree
> result.end();
>
here is how this could look in XmlSerializer (full example code at the
end of this email):
serializer.startTag(null, "department")
.startTag(null, "employee").attribute(null, "id", "500")
.startTag(null, "firstName").text("Kilgore").endTag(null,
"firstName")
.startTag(null,"lastName").text("Trout").endTag(null,"lastName")
.endTag(null, "employee")
.endTag(null, "department")
.endDocument();
how Swan allows to control indentation - i believe that Swan example
code will put everything in one line?
in XmlSerializer to set indention one needs to use XmlSerializer that
supports optional property and then call:
serializer.setProperty("http://xmlpull.org/v1/doc/properties.html#serializer-indentation",
" ");
to request indentation that uses 4 spaces.as in your example
>This is part of a larger toolkit I'm working on. However, it has no
>dependencies on the rest of the toolkit, and has a different focus, so I
>thought I'd go ahead and release this and see if anyone finds it of any
>interest.
>
i will be interested to see when toolkits is finished and see how it
works with streaming large XML documents.
thanks,
alek
ps. here is example working code using XmlSerializer:
import java.io.IOException;
import java.io.PrintWriter;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import org.xmlpull.v1.XmlSerializer;
//Example code to generate output like this:
//<department>
// <employee id="500">
// <firstName>Kilgore</firstName>
// <lastName>Trout</lastName>
// </employee>
//</department>
public class ExampleSwan {
public static void main (String args[])
throws XmlPullParserException, IOException
{
XmlPullParserFactory factory = XmlPullParserFactory.newInstance(
// System.getProperty(XmlPullParserFactory.PROPERTY_NAME), null);
"org.xmlpull.mxp1.MXParserFactory", null);
XmlSerializer serializer = factory.newSerializer();
//System.out.println("serializer implementation class is "+serializer.getClass());
serializer.setOutput(new PrintWriter(System.out));
// now try to set some nice indenting -- need to catch exception as this is optional in API
try {
serializer.setProperty(
"http://xmlpull.org/v1/doc/properties.html#serializer-indentation", " ");
} catch(Exception ex) {
}
serializer.startTag(null, "department")
.startTag(null, "employee").attribute(null, "id", "500")
.startTag(null, "firstName").text("Kilgore").endTag(null, "firstName")
.startTag(null,"lastName").text("Trout").endTag(null,"lastName")
.endTag(null, "employee")
.endTag(null, "department")
.endDocument();
}
}
--
"Mr. Pauli, we in the audience are all agreed that your theory is crazy.
What divides us is whether it is crazy enough to be true." Niels H. D. Bohr
|