thilo
thilo

Reputation: 127

XML parsing using JAXB

I'm new to xml parsing. I worked with DOM to parse the xml for practice. Now I thought to move some to other xml parsing framework. So I have chosen JAXB parser.For my requirement, I could not create getter setter for all xml tags. Because the xml which I will get is dynamic. So I do not know the tags before hand to create getter/setter.I've referred this link http://www.mkyong.com/java/jaxb-hello-world-example/. Is there any way to do parsing without creating getter and setter.Please make me clear.

Upvotes: 1

Views: 5605

Answers (4)

bdoughan
bdoughan

Reputation: 148977

You could leverage the @XmlAnyElement and XmlAnyAttribute annotations to map the extra content. If you don't want get/set methods just add @XmlAccessorType(XmlAccessType.FIELD) on your class.

Customer

In the class below we map a specific XML attribute and element, and then use the @XmlAnyElement annotation to map any other elements that may appear, and @XmlAnyAttribute to map any other attributes that may appear.

import java.util.*;
import javax.xml.bind.annotation.*;
import javax.xml.namespace.QName;

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

    @XmlAttribute
    int id;

    @XmlAnyAttribute
    Map<QName, String> otherAttributes;

    String name;

    @XmlAnyElement(lax=true)
    List<Object> otherElements;

}

input.xml

We will unmarshal the following XML document in the demo code.

<?xml version="1.0" encoding="UTF-8"?>
<customer id="123" status="good">
    <name>Jane Doe</name>
    <address>
        <street>1 A Street</street>
        <city>Any Town</city>
    </address>
    <phone-number>555-1111</phone-number>
</customer>

Demo

The following document will unmarshal the XML input, dump all the resulting objects contents to System.out and the marshal the object back to XML.

import java.io.File;
import java.util.Map.Entry;
import javax.xml.bind.*;
import javax.xml.namespace.QName;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Customer.class, Address.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum14272453/input.xml");
        Customer customer  = (Customer) unmarshaller.unmarshal(xml);


        // Mapped XML Attribute
        System.out.println("customer.id");
        System.out.println("    " + customer.id);

        // Other XML Attributes
        System.out.println("customer.otherAttributes");
        for(Entry<QName, String> entry : customer.otherAttributes.entrySet()) {
            System.out.println("    " + entry);
        }

        // Mapped XML Element
        System.out.println("customer.name");
        System.out.println("    " + customer.name);

        // Other XML Elements
        System.out.println(customer.otherElements);
        for(Object object : customer.otherElements) {
            System.out.println("    " + object);
        }

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(customer, System.out);
    }

}

Output

Below is the output from running the demo code, note how all the fields are populated with data from the XML document.

customer.id
    123
customer.otherAttributes
    status=good
customer.name
    Jane Doe
customer.otherElements
    forum14272453.Address@24f454e4
    [phone-number: null]
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customer id="123" status="good">
    <name>Jane Doe</name>
    <address>
        <street>1 A Street</street>
        <city>Any Town</city>
    </address>
    <phone-number>555-1111</phone-number>
</customer>

For More Information

Upvotes: 2

Evgeniy Dorofeev
Evgeniy Dorofeev

Reputation: 135992

This is going to be dynamic. unmarshal calls Customer.setElements; marshal calls Customer.getElements

@XmlRootElement
class Customer {
    @XmlAnyElement
    public void setElements(List<Element> list) {
        for (Element e : list) {
            String name = e.getNodeName();
            String value = e.getTextContent();
        }
    }

    public List<Element> getElements() throws ParserConfigurationException {
        Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        List<Element> list = new ArrayList<>();
        Element e = doc.createElement("e1");
        e.setTextContent("v1");
        list.add(e);
        return list;
    }
}

Upvotes: 0

AurA
AurA

Reputation: 12363

For JAXB you should create variables and corresponding getters and setters for all XML tags that you might get dynamically. In case you have a tag (that you get dynamically) but you don't have a corresponding mapped variable in the Java class then you will get JAXB Exception.

Hence, you can have a tag defined in JAXB Java Class but comming in request, but the reverse a tag not defined in JAXB Class but comming in XML will give you an exception.

Upvotes: 1

lyomi
lyomi

Reputation: 4370

Jackson, renowned for its JSON processor, also has XML parsing support, and it does a great job of reflection so that it does the parsing even when there are no getters and setters. Give it a try.

Upvotes: -1

Related Questions