2

I'm looking for a Java library that would allow me to marshal XML to a Java object tree, and vice versa. There are plenty of libraries that would allow me to bind XML to JavaBeans generated by some code generation tool, however, I don't need those (JAXB, JiBX, Castor and so on).

What I need is a tool which would consume a schema file and an xml file and then return a combination of Maps, Lists and Objects in a manner similar to Jackson's simple data binding (when it is possible, of course). Jackson is intended for JSON, not for XML; and it lacks the ability to take a schema file in account (because JSON Schema is too immature at the moment).

Can I adapt some existing tools to solve my problem, or should I roll out my own solution with DOM and XSOM?

Marat Salikhov
  • 6,367
  • 4
  • 32
  • 35
  • 1
    I use JAXB without code generation. Works quite well. – tkr Jul 15 '10 at 11:21
  • Objects which correspond to values of primitive type will have types according to the schema (i. e. xs:boolean is a Boolean), and complex types would be represented as maps (maybe two -- one for attributes, and one for sub-elements) or lists of maps. – Marat Salikhov Jul 15 '10 at 11:22
  • 1
    I'm not sure this is feasible. XML contains much more information than JSON (e.g. namespaces, elements vs attributes), and simple Java types are not rich enough to represent this. Even if your specific XML doesn't use these, any framework would have to support them. The comparison to JSON and Jackson doesn't really hold. – skaffman Jul 15 '10 at 11:23
  • tkr, I can't figure out quick enough how to solve my problem with JAXB. Could you give me some directions? – Marat Salikhov Jul 15 '10 at 11:23
  • Yes, the thing is that I need it to work with many different xsd schemas, which would get loaded at runtime. – Marat Salikhov Jul 15 '10 at 11:24
  • Well, every javaBean generated by JAXB is really isomorphic to a HashMap of its properties, so why not? – Marat Salikhov Jul 15 '10 at 11:30
  • @kohomologie: The classes generated by JAXB have a lot of metadata in annotations. Using standard types like String and Integer would have no such meta data. – skaffman Jul 15 '10 at 11:35
  • All these pieces of metadata are contained in xsd file anyway, and a marshaller/unmarshaller would have access to it at runtime; in my case, we may just discard the metadata (I mean, recognizing the consequences of doing so). – Marat Salikhov Jul 15 '10 at 11:38
  • 1
    Acutally I did not get your requirements. For runtime dependent objects with dynamic attributes I would not use JAXB. Probably dom4j, jdom or axiom would be the correct choice. They don't provide a mapping to objects as a Map. But is a node object worse than a map? I would consider jdom: doc.getRootElement().getChild("Person").getChild("Name") is not so much different than a map of maps. – tkr Jul 15 '10 at 11:47
  • You see, I need it to preserve types of values (as described in schema file); that is needed for further processing. What I actually need is JSON with a decent schema and validation tools, not XML; but lack of schema for JSON forces me to look into XML. – Marat Salikhov Jul 15 '10 at 11:51
  • In fact, I need somewhat more strongly typed API for XML, that would cast simple type values to its Java counterparts while reading the xml. JAXB seems too rigid, and JDOM too loose (or maybe I'm clueless about them). – Marat Salikhov Jul 15 '10 at 11:57

2 Answers2

1

MOXy's Dynamic JAXB

MOXy offers a dynamic JAXB implementation. You can bootstrap from an XML schema and instead of static classes you can interact with instances of DynamicEntity with generic get/set methods:

FileInputStream xsd = new FileInputStream("src/example/customer.xsd");
DynamicJAXBContext jaxbContext = 
    DynamicJAXBContextFactory.createContextFromXSD(xsd, null, null, null);

FileInputStream xmlInputStream = new FileInputStream("src/example/dynamic/customer.xml");
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
DynamicEntity customer = (DynamicEntity) unmarshaller.unmarshal(xmlInputStream);

System.out.println(customer.<String>get("name"));

For more information see:

Service Data Objects (SDO)

You could also use Service Data Objects for this (JSR-235).

FileReader xsd = new FileReader("customer.xsd");
XSDHelper.INSTANCE.define(xsd, null);

FileReader xml = new FileReader("input.xml");
XMLDocument doc = XMLHelper.INSTANCE.load(xml, null, null);

DataObject customerDO = doc.getRootObject();
int id = customerDO.getInt("id");
DataObject addressDO = customerDO.getDataObject("contact-info/address");

For more information see:

bdoughan
  • 147,609
  • 23
  • 300
  • 400
  • DynamicEntities and SDO look like something that would do the job. Thank you! – Marat Salikhov Aug 11 '10 at 19:56
  • 1
    EclipseLink includes the MOXy component and is the SDO reference implementation so it's a good place to start http://www.eclipse.org/eclipselink/ – bdoughan Aug 11 '10 at 20:01
  • 1
    For Dynamic JAXB I would recommend getting the latest 2.1.1 build http://www.eclipse.org/eclipselink/downloads/nightly.php. It has some bug fixes related to list properties. – bdoughan Aug 11 '10 at 20:09
0

Looks like SOAP. An option is Apache Axis (we use it a lot), but there are other implementations.

G B
  • 2,951
  • 2
  • 28
  • 50