1

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.

4 Answers 4

2

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

Sign up to request clarification or add additional context in comments.

Comments

1

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.

5 Comments

Yes I know that,Is there any other way to do or any other framework?
I have also used XStream before but it also has the restriction similar to JAXB.
A JAXB (JSR-222) implementation by default will not throw an exception for an unexpected attribute/element. You can specify a custom ValidationEventHandler on the Unmarshaller to make this happen if you wish. You can also enable this behaviour by specifying an instance of Schema on the Unmarshaller to enable validation. If you want the unmapped content you can leverage @XmlAnyAttribute and @XmlAnyElement: stackoverflow.com/a/14276830/383861
Thanks @BlaiseDoughan I did not know that, I have more thing to ask .... I went through your blog post, it dated Dec 21 so is it a new feature or it has been there since a long time, I am using xjc included with Java 6 U 37, so is it included with that version ?
@AurA - Yes @XmlAnyElement(lax=true) would be included with that version.
0

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;
    }
}

1 Comment

i tried this ,while unmarshalling we need getter of that element,how it is possible? i tried like public Element getElement(){ return element; } ...getting null as result
-1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.