Why yet another xml tool?
To make it clear: At the moment xvantage is in its early stage (one week old) and I hacked it down in some hours of my spare time. So it is not a fully fledged and bugless solution like the other ones should be.
But it has some new ideas included to make the serialization as easy as XStream and XmlEncoder, but to make the xml checkable through an xsd file. The advantage of a valid xml is first of all: “then you know all is fine” and second “It is nice to read and editable from a person!”. The latter one was very important for me and is really important for xml configuration files.
Apache Digester was another candidate but the set up was relative complex and the dependencies are to big for me. And last but not least: you need an additional, not further developed library (Betwixt) to make writing working too! So xvantage seems to solve at least these two problems: it is small and it can write xml from your POJOs and read it back.
How would it look like to write my objects?
// Create a data pool with all your POJOs you want to serialize
DataPool pool = new DefaultDataPool();
Map<Long, SimpleObj> map = pool.getData(SimpleObj.class);
map.put(0L, new SimpleObj("test"));
StringWriter writer = new StringWriter();
The resulting xml looks like
<?xml version="1.0" encoding="UTF-8"?>
// get xml from somewhereWhy does xvantage needs the DataPool interface?
StringReader iStream = new StringReader(
" <myobject><name>test</name></myobject>" +
// mount to /path/ with an alternative name 'myobject' instead of the default which would be simpleObj
// this is the preferred way for mounting, because otherwise class refactoring results in different xml
DataPool pool = xadv.readObjects(iStream);
// get the first SimpleObj and check the name
SimpleObj obj = pool.getData(SimpleObj.class).values().iterator().next();
Without it it couldn’t handle references properly. And now with this DataPool interesting use cases arises, e.g. where parts of an object graph should be refreshed through xml (imagine you grab some objects as xmls through HTTP GET …)
Why do we need to mount classes?
To mount a class means: xvantage should track every occurance of that class as references and should NOT nest the object within other objects.
This looks interesting, but does it works for more complex objects?
Yes, it should. I could successfully embed this in my TimeFinder project, where I tried to persist 4 entities (some of them with hundreds of objects and several references) and read them successfully back. Objects which are not mounted explicitly will be nested within mounted objects like in xstream.
Look into this for more information.
Is xvantage an xml binding tool?
No, it is an xml processor. So serialization and deserialization is easily possible if you start from Java code. At the moment it is nearly impossible to start from xml. Use JAXB or JiBX in that case.
What is are the disadvantages?
- As I mentioned earlier: it is may be not so stable like all the others, because it is in early development
- It is not (yet?) so powerful and configurable like JAXB and all the others. So at the moment you cannot make your dream xml happen (i.e. not suited for binding)
- may be not so fast
- not thread save, you have to use multiple instances of xvantage
- a no-arg constructor (at least private), getter and setters for all classes are required to use xvantage
And what are the advantages?
There are several
- easy xml (de-)serialization
- small library <50KB (without dependencies!)
- junit tested
- cross references are allowed! So you can reference even between documents and you could read/write from/to multiple files!
- the xml could be checked via xsd (but no must)
- no deeply nested unreadable xml (the same as 6.)
- no checked exceptions
- no license issues and free source code (public domain!)
How can I use it?
Just clone the git repository:
git clone git://github.com/karussell/xvantage.git
mvn clean install -Dmaven.test.skip=true
How does it work in theory?
- Xvantage writes the object to xml (via SAX). The object will be directly converted to xml if it is a primitive type, a collection (list, set), a map, an array, your own implementations of such an interface or a BitSet.
- If the values of a collection or a property references to a mounted POJO it will write only the id
- If no id was found (in case we have an unmounted POJO) the POJO will be written directly as subtree to the current object.
- It reads the xml tree via SAX and reads discrete objects according to the mounted classes via DOM
- If the object is a mounted POJO it will read the id and try to set the properties from the xml structure. If an object with the given id already exist, this instance will be used to fill in the properties from the xml nodes.
- If a setter is one of the mounted classes a new object with the id (from xml) will be created and the properties will be filled later.
- If the object is a collection it will fill the collection from the values
- If the object is not a mounted POJO it will try to read the nested xml structure to set the properties
Be constructive and tell me facts (maybe such a tool already exists :0!). Use comments or peathal at yaahooo dot de.