Java object to XML schema - java

If you have a Java object and an XML schema (XSD), what is the best way to take that object and convert it into an xml file in line with the schema. The object and the schema do not know about each other (in that the java classes weren't created from the schema).
For example, in the class, there may be an integer field 'totalCountValue' which would correspond to an element called 'countTotal' in the xsd file. Is there a way of creating a mapping that will say "if the object contains an int totalCountValue, create an element called 'countTotal' and put it into the XML".
Similarly, there may be a field in the object that should be ignored, or a list in the object that should correspond to multiple XML elements.
I looked at XStream, but didn't see any (obvious) way of doing it. Are there other XML libraries that can simplify this task?

I believe this can be achieved via JAXB using it's annotations. I've usually found it much easier to generate Objects from JAXB ( as defined in your schema) using XJC than to map an existing Java object to match my schema. YMMV.

I'm doing Object do XML serialization with XStream. What don't you find "obvious" with this serializer? Once you get the hang of it its very simple.
In the example you provided you could have something like this:
...
XStream xstream = new XStream(new DomDriver());
xstream.alias("myclass", MyClass.class);
xstream.aliasField("countTotal", MyClass.class, "totalCountValue");
String xml = xstream.toXML(this);
...
for this sample class:
class MyClass {
private int totalCountValue;
public MyClass() {
}
}
If you find some serializer more simple or "cool" than this please share it with us. I'm also looking for a change...
Check the XStream mini tutorial here

I use a java library called JiBx to do this work. You need to write a mapping file (in XML) to describe how you want the XML Schema elements to map to the java objects. There are a couple of generator tools to help with automating the process. Plus it's really fast.

I tried out most of the libraries suggested in order to see which one is most suited to my needs. I also tried out a library that was not mentioned here, but suggested by a colleague, which was a StAX implementation called Woodstox.
Admittedly my testing was not complete for all of these libraries, but for the purpose mentioned in the question, I found Woodstox to be the best. It is fastest for marshalling (in my testing, beating XStream by around 30~40%). It is also fairly easy to use and control.
The drawback to this approach is that the XML created (since it is defined by me) needs to be run through a validator to ensure that it is correct with the schema.

You can use a library from Apache Commons called Betwixt. It can map a bean to XML and then back again if you need to round trip.

Take a look at JDOM.

I would say JAXB or Castor. I have found Castor to be easier to use and more reliable, but JAXB is the standard

Related

How to prevent JAXB from writing unused namespaces during marshalling

Has someone ever been able to remove unused namespaces during marshal of an object using JAXB? Here is a link of the requested feature: https://github.com/javaee/jaxb-v2/issues/103 (see description)
Is there a property for configuring JAXB for this?
Has this been fixed in MOXy?
I am currently traversing the object that needs to be marshalled and extract all classes that need to be bound into Class[] classesToBeBound.
Then I create a new JAXBContext.newInstance(classesToBeBound)
The unused namespaces now are not included in the XML.
I know that xml validation is valid even with the unused namespaces but to me this is something a framework should handle.
The following link https://blogs.oracle.com/enterprisetechtips/entry/customizing_jaxb mentions various fixed (see middle of the text somewhere) but when trying to find the solution in those links either the link is broken or no-one really solved it.
Any comments are welcome.
(EDIT)
Plain text:
GIVEN
a new instance of JAXBContext and add 2 classes with each a separate namespace.
WHEN
marshalling a class that has these 2 classes as a property but only 1 of them is not null
THEN
I expect only the namespace of the property that is not null to be visible in the XML.
BUT the ACTUAL is
that both namespaces are in the xml.
So my question was how can I remove or tell JAXB to NOT write the unused namespaces?
To put it in java-code:
GIVEN
public class Foo{
private Bar bar; //namespace something2
private User user; //namespace user
}
WHEN
JAXBContext c = JAXBContext.newInstance(Foo.class, Bar.class, User.class);
...
Foo foo = new Foo();
foo.setBar(null);
foo.setUser(new User("Bob"));
marshaller.umarshal(foo);
THEN I expect the xml to be
<foo xmlns="something1" xmlns:user="user">
<user:name>Bob</user:name>
</foo>
BUT the ACTUAL is (note the something2 namespace)
<foo xmlns="something1" xmlns:user="user" xmlns:bar="something2">
<user:name>Bob</user:name>
</foo>
Of course this is a simplified example and our specification of a type has around 30 different namespaces.
As far as I know, this is indeed not possible in JAXB - and is actually a well-known issue. As you have noticed it, the list of produced namespaces are the ones that have been registered in your JAXBContext, and not the ones that are effectively used when marshalling :-(
I the past, I used the same workaround as you (identify the various used classes and narrow the JAXBContext to this limited set of classes).
Another typical workaround is a 2-step processing: a first marshalling with JAXB, followed by a XSLT transformation to get rid of let's says "polluting" namespaces.
This may not be possible as while marshaling of this objects hierarchy happen, at the time of creating root tag, information about which objects are null v/s not null may not be available. Any attempt to get this information in advance may also have side-effects associated with it as respective accessor methods are invoked. Hence JAXB will statically use info from JAXBContext to have this information populated.
You can try using a different javax.xml.bind.Marshaller implementation.
For example org.eclipse.persistence.jaxb.JAXBMarshaller implementation deals well with this case and remove all unnecessary namespaces when marshall the object.
To do so you need to do the next steps:
Add eclipselink-2.6.5.jar to the classpath in order to use the org.eclipse.persistence.jaxb.JAXBMarshaller. If you're using gradle you can add compile 'org.eclipse.persistence:eclipselink:2.6.5' to your dependencies.
Create a jaxb.properties file in the same package where you've the objects to marshall (following the example in your question - JAXBContext c = JAXBContext.newInstance(Foo.class, Bar.class, User.class);, in the package of one of these classes Foo, Bar or User).
In the jaxb.properties file, add the follow property which specify the desired Context factory:
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
Doing this, the org.eclipse.persistence.jaxb.JAXBMarshaller will be used as a javax.xml.bind.Marshaller implementation on Runtime. And then no unnecessary namespaces will appear when you marshall the objects.
I tried the solution albciff suggested in this thread and it turns out that Eclipse Moxy handles this much better than the reference implementation (org.glassfish.jaxb).
Here's info on how to switch to the Moxy implemenation of JAXB:
https://wiki.eclipse.org/EclipseLink/Examples/MOXy/JAXB/SpecifyRuntime
The documentation doesn't specify it but you can also change the jaxb implemenation with just a single configuration file instead of a jaxb.properties in each package where your jaxb annotated classes exists. Just create a file META-INF/services/javax.xml.bind.JAXBContext (yep unconventional filename) with the contents:
org.eclipse.persistence.jaxb.JAXBContextFactory
This makes the jaxb ContextFinder use the Eclipse Moxy implementation for all jaxb marshalling in the jvm.
Another option is to use a system property -Djavax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
Disclaimer though: The namespaces declaration aren't minimized/optimized for the current payload, but at least it doesn't include ALL namespaces that are part of the jaxb grammar. The integration I'm working on went from a staggering 700+ declared namespaces (about 60KB worth of useless overhead per sent message) to at best 3 declarations in a message. Though for messages which have a lot of different types in them, all of the namespaces which are valid in that particular message is declared. That means in some case I still get ~30 declared namespaces when only one would suffice for the current payload.
I guess that SOAP isn't the way to go if you need to optimize on bandwidth.
Yes, they could be omitted. I'm not sure I understood the problem you face correctly. But there is no problem to marshal an object without namespaces.
Try something like this marshaller.setProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION, "class for which namepsace not needed"); in your case it should be
marshaller.setProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION, bar.class);

Serializing java objects with respect to xml schema loaded at runtime

I call an XML document three-layered if its structure is laid out as following: the root element contains some container elements (I'll call them entities), each of them has some simpleType elements inside (I'll call them properties).
Something like that:
<data>
<spaceship>
<number>1024</number>
<name>KTHX</name>
</spaceship>
<spaceship>
<number>1624</number>
<name>LEXX</name>
</spaceship>
<knife>
<length>10</length>
</knife>
</data>
where spaceship is an entity, and number is a property.
My problem is stated below:
Given
schema: an arbitrary xsd file describing a three-layered document, loaded at runtime.
xmlDocument: an xml document conforming to the schema.
Create
A Map<String, Map <String, Object>> containing data from the xmlDocument, where first key corresponds to entity, second key correponds to this entity's property, and the value corresponds to this property's value, after casting it to a proper java type (for example, if the schema sets the property value to be xs:int, then it should be cast to Integer).
What is the easiest way to achieve this result with existing libraries?
P. S.
JAXB is not really an option here. The schema might be arbitrary and unknown at compile-time. Also I wish to avoid an excessive use of reflection (associated with converting the beans to maps). I'm looking for something that would allow me to make the typecasts while xml is being parsed.
I think XMLBeans is worth a shot; saved the day more than once...
Basically you run an ant script to generate the beans handling the schema, then you iterate over the nodes to build your map.
I think JAXB (tutorial here) is the easiest way to do this.
Create your XML structure like:
#XmlRootElement
class data {
public List<SpaceShipType> spaceship;
public KnifeType knife;
}
class SpaceShipType {
public int number;
public String name;
}
class KnifeType {
public int length;
}
Then create the object tree, and use JAXB.marshall() to write the XML.
If you have an existing XSD, use the xjc tool to create the classes for you.
You will need reflections if the schema is unknown at compile time.
I suggest to take a look at some other tools like xstream.
I could recommend the simple framework or you could do parsing/wrinting xml with pure dom4j as I did in the timefinder project. I used the 'pure' approach because I had cycles in my object graph, but I wanted that the xml could be validated with an xml schema (and I did not want to use JAXB)
I have finally went with using Castor library for parsing the schema and assigning data types manually.

Best approach to object XML Serialization in Java

I am writing the service to implement the audit in our application wherein users can view the status of a particular entity before and after any modification and should also be able to roll it back. We have decided to store the XML Serialized object in the databse in XML_TYPE column.
I am new to serialization, I don't know how to achieve the same, any changes needs to be done to the object to be serialized or do we need to have any mapping XML. Can someone please suggest some good libraries, I understand there are lot of those available in the market like JAXB, JIBX, JABX, XStream and etc. Which one would be good and how to use it.
Any help is highly appreciated.
Regards,
Ravi.
Of course, the best for entities is having POJO's (Plain Old Java Objects). No strange properties, references or methods. It simplifies serializing and keeps your model objects neutral from frameworks and strange layers like persistence, UI, remote-access and so on.
XStream: simplicity
I'd suggest using XStream library for serializing. It tries to be the simplest way to serialize and deserialize objects to XML.
You should think searialization this way:
indicate what class is the object
try to serialize each property
So, these are the two problems to resolve in serializing. XStream lets you create a serializer (XStream class), (OPTIONALLY) indicate what tag name use for each class and (OPTIONALLY) indicate the aliases for properties.
So if you have something like:
package pack;
Person
+ mom: Person
+ dad: Person
it will write with no configuration:
<pack.Person>
<mom>
<pack.Person>
...
</pack.Person>
</mom>
<dad>
<pack.Person>
...
</pack.Person>
</dad>
</pack.Person>
But if you tell it to map package.Person to it will use that tag. You can tell it to write property "mom" as "mother" and things like that.
XStream xs = new XStream();
xs.alias("person", Person.class);
xs.aliasAttribute(Person.class, "mom", "mother");
References
XStream also lets you indicate what kind of references you want:
no references: serialize an object
each time it founds it in the object
tree
absolute references: the second time
an object is found it saves a
reference using the absolute path of
the first instance
(/people/person[4]/teacher)
relative references: the same, but
using a relative reference from this
point (../../person[4]/teacher)
JAXB is the standard. In the simplest (and most common case) you just annotate your entities with JAXB annotations, and use a Marshaller to marshal the object to XML.
You can use either Sun's reference implementation, or Apache JaxMe.
XStream is a good alternative as far as I know, although I haven't used it.

Simple Java Xml to POJO mapping/binding?

I'm trying to figure out the simplest way to map an xml file to to a plain old java object.
Note: That in my example the xml doesn't quite match up with my intended POJO.
///////// THE XML
<?xml version="1.0" encoding="UTF-8"?>
<Animal>
<standardName>
<Name>Cat</Name>
</standardName>
<standardVersion>
<VersionIdentifier>V02.00</VersionIdentifier>
</standardVersion>
</Animal>
////// THE INTENDED POJO
class Animal
{
private String name;
private String versionIdentifier;
}
Regular JAXB (with annotations) won't work as the JAXM Element name annotations don't allow me to specifiy nested elements. (i.e. standardName/Name).
I've looked at Jibx but it seems overly complicated, and no full examples are provided for what I want to do.
Castro seems like it would be able to do what I want (using mapping files), but I wonder if there are any other possible solutions. (Possibly that would allow me to skip mapping files, and just allow me to specify everything in annotations).
Thanks
EclipseLink JAXB (MOXy) allows you to do the path based mapping that you are looking for:
#XmlRootElement
class Animal
{
#XmlPath("standardName/Name/text()")
private String name;
#XmlPath("standardVersion/VersionIdentifier/text()");
private String versionIdentifier;
}
For more information see:
http://bdoughan.blogspot.com/2010/09/xpath-based-mapping-geocode-example.html
http://bdoughan.blogspot.com/2010/07/xpath-based-mapping.html
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/GettingStarted/MOXyExtensions
EclipseLink also allows the metadata to be specified using an external configuration file:
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/GettingStarted/ExternalizedMetadata
This article may help you... it only requires you to know xpath
http://onjava.com/onjava/2007/09/07/schema-less-java-xml-data-binding-with-vtd-xml.html
Jakarta Commons Digester should do what you want.
Alternatively, I would recommend writing a transformation class that uses XPath to retrieve elements from the XML.
I consider JiBX the best of the bunch (JAXB, Castor, XMLBeans, etc.), particularly because I favor mapping files over annotations. Admittedly it has a decent learning curve, but the website has a lot of good examples. You must have missed the tutorial.
If you are only going one way (XML --> POJO) you could use Digester.
Side comment: I prefer mapping files over annotations because annotations:
clutter the code (especially when using annotations from several products)
mix concerns (XML, database, etc. in domain layer)
can only bind to a single XML (or database, or web service, etc.) representation

JAXB is good until I need to do something complex. What are the alternatives?

JAXB works well until I need to do something like serialize beans for which I cannot modify the source. If the bean doesn't have a default constructor or if it refers to objects I want to mark transient then I'm stuck writing a separate bean which I can annotate and then manually copy the information over from the other bean.
For instance, I wanted to serialize exception objects, but found that the only way to do that was use a hack that required using com.sun.* classes.
So, what alternatives are there? What's the next most popular xml serializing api? It would be nice to be able to do things like:
Choose at serialization time whether to include certain fields in the result. (marking things transient when running the serializer).
Handle loops in the object graph by using references or something other than just dying.
Perhaps annotate an object so that in version 1 it serializes things in one way and in version 2 it serializes them in another. Then when serializing I just choose which version of the object ot serialize.
Have a way to generate XSDs from annotations on an object.
Basically I just want more flexibility than I currently have with JAXB.
Well the standard answer for wanting a uber configurable serialisation framework is xstream.
JAXB is a spec, so you can pick from different implementations. EclipseLink JAXB (MOXy) has extensions for what you are asking:
Externalized Metadata
Useful when dealing with classes for which you cannot annotate the source or to apply multiple mappings to an object model.
http://bdoughan.blogspot.com/2010/12/extending-jaxb-representing-annotations.html
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/EclipseLink-OXM.XML
XPath Based Mapping
For true meet-in-the-middle OXM mapping:
http://bdoughan.blogspot.com/2010/09/xpath-based-mapping-geocode-example.html
http://bdoughan.blogspot.com/2011/03/map-to-element-based-on-attribute-value.html
http://bdoughan.blogspot.com/2010/07/xpath-based-mapping.html
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/GettingStarted/MOXyExtensions
JPA Compatibility
Including support for bi-directional relationships.
http://bdoughan.blogspot.com/2010/07/jpa-entities-to-xml-bidirectional.html
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/JPA
Also look at JIBX. It's a good xml<->object mapper. My experience is though that if your objects have a somewhat funky relationships it's often easier to create a wrapper object that hides that complexity and then map that object with JIBX.
XStream is a popular XML serialisation library that claims to be able to serialize just about anyting, regardless of constructors or other problems (even deserialize final fields). Give it a try.
Requires no modifications to objects. Serializes internal fields, including private and final. Supports non-public and inner classes. Classes are not required to have default constructor.

Categories