How can I add xml attributes to jaxb annotated class XmlElementWrapper? How can I add xml attributes to jaxb annotated class XmlElementWrapper? xml xml

How can I add xml attributes to jaxb annotated class XmlElementWrapper?


I got a better solution for your question.

For making Xml Java object, use the following code:

import java.util.*;import javax.xml.bind.annotation.*;@XmlRootElement(name="myList")public class Root {    private String number;    private List<String> someList;    @XmlAttribute(name="number")    public String getNumber() {        return number;    }    public void setNumber(String number) {        this.number = number;    }    @XmlElement(name="myElement")    public List<String> getSomeList() {        return someList;    }    public void setSomeList(List<String> someList) {        this.someList = someList;    }     public Root(String numValue,List<String> someListValue) {        this();        this.number = numValue;        this.someList = someListValue;      }    /**     *      */    public Root() {        // TODO Auto-generated constructor stub    }

}

To run the above code using JAXB, use the following:

   import java.util.ArrayList;import java.util.List;import javax.xml.bind.*;public class Demo {        public static void main(String[] args) throws Exception {            List<String> arg = new ArrayList<String>();            arg.add("FOO");            arg.add("BAR");            Root root = new Root("123", arg);            JAXBContext jc = JAXBContext.newInstance(Root.class);            Marshaller marshaller = jc.createMarshaller();            marshaller.marshal(root, System.out);        }}

This will produce the following XML as the output:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>    <myList number="123">        <myElement>FOO</myElement>        <myElement>BAR</myElement>    </myList>

I think this is more helpful you.

Thanks..


The MOXy JAXB implementation (I'm the tech lead) has an extension (@XmlPath) to handle this case:

import java.util.*;import javax.xml.bind.annotation.*;import org.eclipse.persistence.oxm.annotations.XmlPath;@XmlRootElement@XmlAccessorType(XmlAccessType.FIELD)public class Root {    @XmlPath("myList/@number")    private int number;    @XmlElementWrapper(name="myList")     @XmlElement(name="myElement")     private List<String> someList = new LinkedList<String>();    public int getNumber() {        return number;    }    public void setNumber(int number) {        this.number = number;    }    public List<String> getSomeList() {        return someList;    }    public void setSomeList(List<String> someList) {        this.someList = someList;    } }

Will produce the following XML:

<?xml version="1.0" encoding="UTF-8"?><root>   <myList number="123">      <myElement>FOO</myElement>      <myElement>BAR</myElement>   </myList></root>

When this code is run:

import javax.xml.bind.*;public class Demo {    public static void main(String[] args) throws Exception {        JAXBContext jc = JAXBContext.newInstance(Root.class);        Root root = new Root();        root.setNumber(123);        root.getSomeList().add("FOO");        root.getSomeList().add("BAR");        Marshaller marshaller = jc.createMarshaller();        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);        marshaller.marshal(root, System.out);    }}

To get this to work using strictly standard JAXB code you will need to use an XML Adapter:

Note:

To use MOXy JAXB you need to add a file called jaxb.properties in with your model classes with the following entry:

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory


If you are not using MOXy or just want to stick to standard JAXB annotations, you can extend upon Noby's answer to add support for a generic wrapper class. Noby's answer only currently supports a list of strings, but say for example you're going to be using the same generic wrapper class for several different classes. In my example, I want to create a generic "PagedList" class that will marshall to something that looks like a list, but also contains information about the page offset and the total number of elements in unpaged list.

The one downside of this solution is that you have to add additional @XmlElement mappings for each type of class that will be wrapped. Overall though, probably a better solution than creating a new class for each pagable elements.

@XmlTypepublic class PagedList<T> {    @XmlAttribute    public int offset;    @XmlAttribute    public long total;    @XmlElements({        @XmlElement(name="order", type=Order.class),        @XmlElement(name="address", type=Address.class)        // additional as needed    })    public List<T> items;}@XmlRootElement(name="customer-profile")public class CustomerProfile {    @XmlElement    public PagedList<Order> orders;    @XmlElement    public PagedList<Address> addresses;}

Marshalling this example would get you:

<customer-profile>    <order offset="1" total="100">        <order> ... </order>        <order> ... </order>        <order> ... </order>        ...    </orders>    <addresses offset="1" total="5">        <address> ... </address>        <address> ... </address>        <address> ... </address>        <address> ... </address>        <address> ... </address>    <addresses></customer-profile>

Hope that helps. This is the solution that I settled upon at least.