0

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?

Prabhath kesav
  • 428
  • 3
  • 6
  • 21

3 Answers3

3

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.

Kai
  • 38,985
  • 14
  • 88
  • 103
  • Will XStream be helpful to map the different XML Tag Name and Class attribute name? – Prabhath kesav May 09 '12 at 07:33
  • Yes, you can define `@XStreamAlias`es for this. – Kai May 09 '12 at 07:36
  • Note that the original question is about turning an xml document into a class, not the other way around. Also, by the way, what you have up there is not a schema, but an xml document. – Miquel May 09 '12 at 07:36
  • @Miquel: XStream can do both! _"XStream is a simple library to serialize objects to XML and back again."_ – Kai May 09 '12 at 07:37
  • Thanks @ user714965, I have gone through it and its very helpful,but otherthan Xstream,Can we do in minimal changes other than this? – Prabhath kesav May 09 '12 at 07:44
  • Xstream is a good Choice,but if I have large number of fields it will be difficult to add aliases,so any better choices? – Prabhath kesav May 09 '12 at 08:58
  • You could generate new Objects which variables are named like the elements in the XML (by JAXB). But then you surely have to make changes on other parts of your code. So you have to make this mapping, there is no way around. – Kai May 09 '12 at 09:03
3

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.

Miquel
  • 15,405
  • 8
  • 54
  • 87
1

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>
bdoughan
  • 147,609
  • 23
  • 300
  • 400