I have XML like this which I get from middleware
<Example library="somewhere">
<book>
<AUTHORS_TEST>Author_Name</AUTHORS_TEST>
<EXAMPLE_TEST>Author_Name</EXAMPLE_TEST>
</book>
</Example>
What I want to do is convert the XML to Java object(and Vice Versa) as:
class Example
{
private String authorsTest;
private String exampleTest;
}
So Is there any way to map these two,The thing to be noted is that XML Tag Name and the Class attribute name is different,So can anyone suggest to implement this with minimal changes?Xstream is a good Choice,but if I have large number of fields it will be difficult to add aliases,so any better choices other than XStream?
What you are looking for is called XML Binding, where you actually turn an xml into a java class based on an xml schema. The reference implementation for this is jaxb but there are many other alternatives.
There are good libraries which does this for you. An easy one is XStream for example.
See this example from the Two Minute Tutorial:
Person joe = new Person("Joe", "Walnes");
joe.setPhone(new PhoneNumber(123, "1234-456"));
joe.setFax(new PhoneNumber(123, "9999-999"));
Now, to convert it to XML, all you have to do is make a simple call to XStream:
String xml = xstream.toXML(joe);
The resulting XML looks like this:
<person>
<firstname>Joe</firstname>
<lastname>Walnes</lastname>
<phone>
<code>123</code>
<number>1234-456</number>
</phone>
<fax>
<code>123</code>
<number>9999-999</number>
</fax>
</person>
I would prefer XStream because it is very easy to use. If you want to do more complex things like generating Java classes from the XML you should have a look at JAXB as Miquel mentioned. But it is more complex and needs more time to get started.
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB 2 (JSR-222) expert group.
Most XML-binding libraries require an object per level of nesting in the XML representation. EclipseLink JAXB (MOXy) has the #XmlPath extension that enables XPath based mapping to remove this restriction.
Example
Below is a demonstration of how the #XmlPath extension can be applied to your use case.
package forum10511601;
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlPath;
#XmlRootElement(name="Example")
#XmlAccessorType(XmlAccessType.FIELD)
class Example {
#XmlAttribute
private String library;
#XmlPath("book/AUTHORS_TEST/text()")
private String authorsTest;
#XmlPath("book/EXAMPLE_TEST/text()")
private String exampleTest;
}
jaxb.properties
To specify MOXy as your JAXB provider you need to add a file named jaxb.properties in the same package as your domain model with the following entry (see Specifying EclipseLink MOXy as Your JAXB Provider).
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
Demo
As MOXy is a JAXB (JSR-222) implementation, you use the standard JAXB runtime APIs (which are included in the JRE/JDK starting with Java SE 6).
package forum10511601;
import java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Example.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum10511601/input.xml");
Example example = (Example) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(example, System.out);
}
}
input.xml/Output
<?xml version="1.0" encoding="UTF-8"?>
<Example library="somewhere">
<book>
<AUTHORS_TEST>Author_Name</AUTHORS_TEST>
<EXAMPLE_TEST>Author_Name</EXAMPLE_TEST>
</book>
</Example>
Related
I have autogenerated java classes from xsd using xsd2java. I cannot modify neither xsd nor the java classes.
Problem: in one class an element of List<JAXBElement> is generated.
If I now add any JAXBElement, the jackson xml marshaller won't show the proper xml element, but the properties of the JAXBElement serialized. Like declaredType, scope, etc. See below.
#XmlRootElement(name = "bookingRequest")
public class AutogeneratedReq {
private List<JAXBElement<?>> someElements;
}
Usage:
AutogeneratedReq req = new AutogeneratedReq();
JAXBElement<?> person = new ObjectFactory().createPerson();
req.getSomeElements().add(person);
Result:
<someElements>
<JAXBElement>
<name>person</name>
<declaredType>net.some.company.Person</declaredType>
<scope>net.some.company</scope><value someattribues="test"/>
<nil>false</nil>
<globalScope>false</globalScope>
<typeSubstituted>false</typeSubstituted>
</JAXBElement>
</someElements>
Question: how can I tell jackson or spring-mvc to generate proper xml, and not JAXBElement serialization explicit?
I don't know which xsd2java utility you currently use, but you can try the following maven plugin to generate Java classes from XSD files.
https://github.com/highsource/jaxb2-basics/wiki/Using-JAXB2-Basics-Plugins
And then you can use following extension to create correctly typed POJO's.
https://github.com/highsource/jaxb2-basics/wiki/JAXB2-Simplify-Plugin
BUT even if you can create typed POJO attributes, the XML file generated from this POJO may not be 100% valid against original XSD file.
<jaxb:bindings multiple="true" node="//xs:element[#name='someElement']//xs:complexType//xs:choice//xs:element">
<simplify:as-element-property/>
</jaxb:bindings>
Probably this question might have been asked. I am new to the conversion of xml to java classes.
I have an xml like this:
<Root>
<Book name="harel" price="5" />
<Book name="xml" price="9" />
</Root>
IS there a way to generate java classes dynamicaly for a structure like this ?
A small correction, i don't have an xsd for the xml
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.
IS there a way to generate java classes dynamicaly for a structure
like this ?
JAXB implementations provide the ability to generate a Java model from an XML schema. The reference implementation which is included in the JDK starting in Java SE 6 is available at:
<JAVA_HOME>/bin/xjc
An example of generating an object model from an XML schema can be found here:
http://blog.bdoughan.com/2010/09/processing-atom-feeds-with-jaxb.html
A small correction, i don't have an xsd for the xml
If you don't have an XML schema you could find a utility to generate an XML schema from an XML document:
Any tools to generate an XSD schema from an XML instance document?
Or start from code.
STARTING FROM CODE
You can also start from code and annotate your model to map to the existing XML structure.
Root
package forum11213872;
import java.util.List;
import javax.xml.bind.annotation.*;
#XmlRootElement(name="Root")
#XmlAccessorType(XmlAccessType.FIELD)
public class Root {
#XmlElement(name="Book")
private List<Book> books;
}
Book
package forum11213872;
import javax.xml.bind.annotation.*;
#XmlAccessorType(XmlAccessType.FIELD)
public class Book {
#XmlAttribute
private String name;
#XmlAttribute
private int price;
}
Demo
package forum11213872;
import java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Root.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum11213872/input.xml");
Root root = (Root) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(root, System.out);
}
}
input.xml/Output
<Root>
<Book name="harel" price="5" />
<Book name="xml" price="9" />
</Root>
Yes, see the castor framework (http://www.castor.org/) or jaxb (http://www.oracle.com/technetwork/articles/javase/index-140168.html)
Try Java Castor. You can specify a xsd and convert it to object. There is also a plugin for Eclipse.
http://www.castor.org/
Have a look at XStream.
It converts between XML and Java and between Java and XML.
Use JAXB, it is included in JavaSE now and you can use XJC to generate the classes from an XSD. However if you truly mean dynamically as in the structure of the XML isn't known till runtime you will need to use something like JDOM.
Is it possible to transform a POJO instance into its XML representation without storing it to DB and load it back again in DOM4J mode (and from XML to POJO)?
I have not used this yet, but DOM4J appears to have some JAXB integration that could be used to convert your POJOs to XML (DOM4J):
http://dom4j.sourceforge.net/dom4j-1.6.1/apidocs/org/dom4j/jaxb/package-summary.html
UPDATE
DOM4J also offers a DocumentResult class that implements javax.xml.transform.Result. You can use JAXB to marshal to this class and then manipulate the resulting DOM4J Document object:
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import org.dom4j.Document;
import org.dom4j.io.DocumentResult;
public class Demo {
public static void main(String[] args) throws Exception {
// Create the JAXBContext
JAXBContext jc = JAXBContext.newInstance(Customer.class);
// Create the POJO
Customer customer = new Customer();
customer.setName("Jane Doe");
// Marshal the POJO to a DOM4J DocumentResult
Marshaller marshaller = jc.createMarshaller();
DocumentResult dr = new DocumentResult();
marshaller.marshal(customer, dr);
// Manipulate the resulting DOM4J Document object
Document document = dr.getDocument();
document.getRootElement().addAttribute("foo", "bar");
// Output the result
System.out.println(document.asXML());
}
}
You don't need anything except JAXB (package javax.xml.bind) which is part of JDK (I think starting from JDK6). Look into JAXBContext and #XmlRootElement annotation for starters
There are many XML serialization libraries, take your pick:
JAXB
DOM4J
XStream
I am a big fan of XStream myself, it is dead simple to use and does not require an .xsd.
I would like to know how to bind an XML tag in a certain namespace to some implementation in Java e.g. the way Mule does with the tags defined in it's various XSD files. Is it related/done with JAXB or is that just for mapping Java beans to XML?
Regards Ola
Check out my article on JAXB and namespaces:
http://bdoughan.blogspot.com/2010/08/jaxb-namespaces.html
With JAXB you can choose the granularity at which namespace information is provided:
At the package level using #XmlSchema
At the type level using #XmlType
At the field/property level using #XmlElement and #XmlAttribute
I dont fully understad your question. Are you asking about unmarshalling ?
If so try use sth like below:
JAXBContext ctx = JAXBContext.newInstance("some.package");
Unmarshaller u = ctx.createUnmarshaller();
XMLInputFactory inFac = XMLInputFactory.newFactory();
XMLStreamReader reader = inFac.createXMLStreamReader(this.getClass().
getResourceAsStream("inputFile.xml"));
JAXBElement<Mule> freestyleElement = u.unmarshal(reader,Mule.class);
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking us to recommend or find a tool, library or favorite off-site resource are off-topic for Stack Overflow as they tend to attract opinionated answers and spam. Instead, describe the problem and what has been done so far to solve it.
Closed 8 years ago.
Improve this question
I have an object graph that I would like to convert to and from JSON and XML, for the purposes of creating a REST-style API. It strikes me that someone must have done this already, but a quick search using Google and Stack Overflow reveals nothing.
Does anyone know of a suitable (Apache or equivalent license preferred) library to do this?
GSON from google : http://code.google.com/p/google-gson/,
or
Jackson the library used in spring :https://github.com/FasterXML/jackson
and I would concur with others suggesting jaxb for XML to pojo, well supported lots of tools : its the standard.
For POJO to XML I suggest using JAXB (there are other libraries as well, such as XStream for example, but JAXB is standardized).
For JSON I don't know anything, but if you want to implement a RESTful API, you might be interested in JSR-311 which defines a server-side API for RESTful APIs and Jersey, which is its reference implementation.
Use Xstream http://x-stream.github.io/ for xml and JSON http://www.json.org/java/ for JSON. I dont think there is one library that does both.
Or write a wrapper which delegates to XStream renderers/JSON renderers depending on what you want.
I think you may be looking for something similar to what is here: JSON.org Java section
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.
EclipseLink JAXB (MOXy) supports mapping a single object model to both XML and JSON with the same metadata:
http://blog.bdoughan.com/2011/08/binding-to-json-xml-geocode-example.html
License Information
http://wiki.eclipse.org/EclipseLink/FAQ/General#How_is_EclipseLink_Licensed.3F
DOMAIN MODEL
Below is the domain model we will use for this example. For this example I'm just using the standard JAXB (JSR-222) annotations which have are available in the JDK/JRE since Java SE 6.
Customer
package forum658936;
import java.util.List;
import javax.xml.bind.annotation.*;
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
String firstName;
#XmlElement(nillable=true)
String lastName;
#XmlElement(name="phone-number")
List<PhoneNumber> phoneNumbers;
}
PhoneNumber
package forum658936;
import javax.xml.bind.annotation.*;
#XmlAccessorType(XmlAccessType.FIELD)
public class PhoneNumber {
#XmlAttribute
int id;
#XmlValue
String number;
}
jaxb.properties
To specify MOXy as your JAXB provider you need to include a file called jaxb.properties in the same package as your domain model with the following entry (see: http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html).
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
XML
input.xml
This is the XML that our demo code will read in and convert to domain objects.
<?xml version="1.0" encoding="UTF-8"?>
<customer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<firstName>Jane</firstName>
<lastName xsi:nil="true"/>
<phone-number id="123">555-1234</phone-number>
</customer>
Things to note about the XML:
The xsi:nil attribute is used to indicate that the lastName is null.
The phone-number element is a complex type with simple content (see: http://blog.bdoughan.com/2011/06/jaxb-and-complex-types-with-simple.html).
JSON
Output
Below is the JSON that was output by running the demo code.
{
"firstName" : "Jane",
"lastName" : null,
"phone-number" : [ {
"id" : 123,
"value" : "555-1234"
} ]
}
Things to note about the JSON:
The null value is used to represent that the lastName is null. There is no presence of the xsi:nil attribute.
The collect of phone numbers is of size 1 and is correctly bound by square brackets. Many libraries incorrectly treat collections of size 1 as JSON objects.
The property of type int was correctly marshalled without quotes.
In the XML representation id was an attribute, but in the JSON representation there is not need for it to be specially represented.
DEMO CODE
In the demo code below we will convert an XML document to objects, and then convert those same instances to JSON.
Demo
MOXy doesn't just interpret JAXB annotations it is a JAXB implementation so the standard JAXB runtime APIs are used. JSON binding is enabled by specifying MOXy specify properties on the Marshaller.
package forum658936;
import java.io.File;
import javax.xml.bind.*;
import org.eclipse.persistence.jaxb.MarshallerProperties;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Customer.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum658936/input.xml");
Customer customer = (Customer) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/json");
marshaller.setProperty(MarshallerProperties.JSON_INCLUDE_ROOT, false);
marshaller.marshal(customer, System.out);
}
}
Json-lib is licensed under the Apache 2.0 license.
It can also transform JSON objects to XML, but you'd need to convert your POJOs to JSON through it first.
Personally I would tackle the two separately; and to convert JSON<->XML via JSON<-> Pojo <-> XML.
With that: Java<->POJO with JAXB (http://jaxb.dev.java.net; also bundled with JDK 1.6) with annotations (XStream is ok too); and for JSON, Jackson's ObjectMapper (http://jackson.codehaus.org/Tutorial). Works nicely with Jersey, and I am use it myself (current Jersey version does not bundle full Pojo data binding by default, but will in near future)
I would actually not use any of xml libs to produce "json": XStream and JAXB/Jettison can produce kind of JSON, but it uses ugly conventions that are rather non-intuitive.
EDIT (18-Jul-2011): Jackson actually has an extension called "jackson-xml-databind" that can read/write XML, similar to JAXB. So it can be used for both JSON and XML, to/from POJOs.
Last I saw on the website, XStream will do both. It supports XML and JSON as serialization targets.
There are almost literally hundreds. My favorites are GSON for POJO <-> JSON and castor-xml for POJO <-> XML.
As a bonus both are licensed under Apache License 2.0 style licenses.
Have a look at Genson library http://code.google.com/p/genson/wiki/GettingStarted.
It is easy to use, performant and was designed with extension in mind.
Actually it does json/java conversion but not xml. However xml support may be added in a future version.
I'm using it in web applications and REST web services in jersey, but also in some cases to store objects in their json form into a database.
Ah and it's under Apache 2.0 license.