41

I have a XML which is used to config some rules, it does not has complex structure, but this configuration is used anywhere in my system, so I want to parse this XML to java object and design as singleton mode, is any good way I can use it to unmarshal XML to Java object directly without write much codes?

I did some research on Google and known JAXB is a choice, my application is just some kinds of tool program which read rule and then follow do stuffs, JAXB could be used for web service more widely, it fit my projects?

If yes, the most important question is, I used xjc to generate java object source class according xsd file, after unmarshal I will directly get these configurationType object, is it necessary I convert again, (from the JaxB classes to my owned java pojo object configuration), I see most coder did this, but why? because they are some data, just from the object generated to JAXB and copy to ourself created POJO object

C.c
  • 1,905
  • 6
  • 30
  • 47
  • It depends entirely on how the XML was written. If by an existing XML beans tool, just keep using that tool. Otherwise you will have to parse it yourself and build your own objects. Too broad. – user207421 Jun 14 '20 at 04:36

5 Answers5

77

JAXB is an ideal solution. But you do not necessarily need xsd and xjc for that. More often than not you don't have an xsd but you know what your xml is. Simply analyze your xml, e.g.,

<customer id="100">
    <age>29</age>
    <name>mkyong</name>
</customer>

Create necessary model class(es):

@XmlRootElement
public class Customer {

    String name;
    int age;
    int id;

    public String getName() {
        return name;
    }

    @XmlElement
    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    @XmlElement
    public void setAge(int age) {
        this.age = age;
    }

    public int getId() {
        return id;
    }

    @XmlAttribute
    public void setId(int id) {
        this.id = id;
    }

}

Try to unmarshal:

JAXBContext jaxbContext = JAXBContext.newInstance(Customer.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
Customer customer = (Customer) jaxbUnmarshaller.unmarshal(new File("C:\\file.xml"));

Check results, fix bugs!

Asad Iqbal
  • 3,241
  • 4
  • 32
  • 52
Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
  • so in this case, I can use Customer as pojo across my system, I don't need to create new pure java pojo class Customer without the annotation in it? – C.c May 03 '13 at 17:41
  • Sure, this is the idea, you read a Customer from xml and continue working with it as is. – Evgeniy Dorofeev May 03 '13 at 17:43
  • @EvgeniyDorofeev Hello I am having trouble with this simliar problem I need to save sub nodes with same tag name. http://stackoverflow.com/questions/41875849/how-to-parse-xml-with-sub-child-node-same-name-different-type-in-java – JayC Jan 27 '17 at 21:52
  • This gives a JAXBException: doesnt contain ObjectFactory.class or jaxb.index. – pHneutre Oct 12 '17 at 13:24
  • jaxb is not an ideal solution. it was removed from java SE. if you want your code to break, keep using it and just wait til you upgrade java – user2914191 Feb 10 '19 at 22:02
  • 1
    @user2914191 what's the issue? You don't blindly upgrade between versions. – Dragas Apr 08 '21 at 11:49
  • Along with this answer, I had to apply the following lines to solve the cast Exception for my usecase(for me the class did not have a @XmlRootElement annotation), thought it will be helpful, JAXBContext jaxbContext = JAXBContext.newInstance(Customer.class); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); Source source = new StreamSource(new File("C:\\file.xml")); JAXBElement root = unmarshaller.unmarshal(source, Customer.class); Customer customer = root.getValue(); Credits to the following stackoverflow link: https://stackoverflow.com/a/707122/3253199 – Sreedhar S May 31 '22 at 09:48
10

One thing that is really important to understand considering you have an XML file as :

<customer id="100">
    <Age>29</Age>
    <NAME>mkyong</NAME>
</customer>

I am sorry to inform you but :

@XmlElement
public void setAge(int age) {
    this.age = age;
}

will not help you, as it tries to look for "age" instead of "Age" element name from the XML.

I encourage you to manually specify the element name matching the one in the XML file :

@XmlElement(name="Age")
public void setAge(int age) {
    this.age = age;
}

And if you have for example :

@XmlRootElement
@XmlAccessorType (XmlAccessType.FIELD)
public class Customer {
...

It means it will use java beans by default, and at this time if you specify that you must not set another

@XmlElement(name="NAME")

annotation above a setter method for an element <NAME>..</NAME> it will fail saying that there cannot be two elements on one single variables.

I hope that it helps.

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
aks
  • 554
  • 6
  • 8
  • How can you do the same with sun elements that have the same name? Something like http://stackoverflow.com/questions/41875849/how-to-utilize-jaxb-for-object-serialization-for-sub-elements-with-same-tag-name – JayC Jan 30 '17 at 18:09
  • "and at this time if you specify that you must not set another..." --- what??? – pavel_orekhov Oct 07 '22 at 14:52
8

For performing Unmarshall using JAXB:

1) Convert given XML to XSD(by yourself or by online convertor),

2) Create a JAXB project in eclipse,

3) Create XSD file and paste that converted XSD content in it,

4) Right click on **XSD file--> Generate--> JAXB Classes-->follow the instructions(this will create all nessasary .java files in src, i.e., one package-info, object factory and pojo class),

5) Create another .java file in src to operate unmarshall operation, and run it.

Happy Coding !!

Soumya Sarkar
  • 95
  • 1
  • 6
2

JAXB is a reliable choice as it does xml to java classes mapping smoothely. But there are other frameworks available, here is one such:

https://code.google.com/p/xmappr/

Juned Ahsan
  • 67,789
  • 12
  • 98
  • 136
1

I find jackson fasterxml is one good choice to serializing/deserializing bean with XML.

Refer: How to use spring to marshal and unmarshal xml?

bluearrow
  • 856
  • 2
  • 11
  • 26