Home > DeveloperSection > Forums > class field become a tag name using JAXB
Kamlakar Singh
Kamlakar Singh

Total Post:194

Posted on    October-16-2014 12:04 AM

 Java Java  XML 

 1 Reply(s)
 724  View(s)
Rate this:

I am using Java and JAXB for XML processing.

I have the following class:

    public class Characteristic {


        private String characteristic;

        private String value;



        public String getCharacteristic() {

            return characteristic;



        public void setCharacteristic(String characteristic) {

            this.characteristic = characteristic;




        public String getValue() {

            return value;



        public void setValue(String value) {

            this.value = value;




    public static void main(String[] args) {

        Characteristic c = new Characteristic();



        Characteristic c2 = new Characteristic();




This is the result that I get:

<characteristics characteristic="store_capacity">40</characteristics>

<characteristics characteristic="number_of_doors">4</characteristics>

I want to get the following result:



How can I achieve this?

Pawan Shukla

Total Post:37

Posted on    October-16-2014 12:13 AM

You can use a combination of @XmlElementRef and JAXBElement to produce dynamic element names.


The idea is:


1.       Make Characteristic a subclass of JAXBElement and override the getName() method to return the name based on the characteristic property.

2.       Annotate characteristics with @XmlElementRef.

3.       Provide the @XmlRegistry (ObjectFactory) with an @XmlElementDecl(name = "characteristic").

Below is a working test.


The test itself (nothing special):


        public void marshallsDynamicElementName() throws JAXBException {

            JAXBContext context = JAXBContext.newInstance(ObjectFactory.class);

            final Characteristics characteristics = new Characteristics();

            final Characteristic characteristic = new Characteristic(

                    "store_capacity", "40");


            context.createMarshaller().marshal(characteristics, System.out);



<?xml version="1.0" encoding="UTF-8" standalone="yes"?>


Let's start with the characteristics root element class. It has a characteristics property which is annotated with @XmlElementRef. This means that the contents should be either JAXBElements or @XmlRootElement-annotated class instances.

@XmlRootElement(name = "characteristics")

        public static class Characteristics {


            private final List<Characteristic> characteristics = new LinkedList<Characteristic>();


            @XmlElementRef(name = "characteristic")

            public List<Characteristic> getCharacteristics() {

                return characteristics;




In order for this to work you also need an ObjectFactory or something annotated with @XmlRegistry having a corresponding @XmlElementDecl:


    public static class ObjectFactory {


        @XmlElementDecl(name = "characteristic")

        public JAXBElement<String> createCharacteristic(String value) {

            return new Characteristic(value);




Recall, the characteristics property must contain either @XmlRootElement-annotated class instances or JAXBElements. @XmlRootElement is not suitable since it's static. But JAXBElement is dynamic. You can subclass JAXBElement and override the getName() method:

    public static class Characteristic extends JAXBElement<String> {


        private static final long serialVersionUID = 1L;

        public static final QName NAME = new QName("characteristic");


        public Characteristic(String value) {

            super(NAME, String.class, value);



        public Characteristic(String characteristic, String value) {

            super(NAME, String.class, value);

            this.characteristic = characteristic;




        public QName getName() {

            final String characteristic = getCharacteristic();

            if (characteristic != null) {

                return new QName(characteristic);


            return super.getName();



        private String characteristic;



        public String getCharacteristic() {

            return characteristic;



        public void setCharacteristic(String characteristic) {

            this.characteristic = characteristic;




In this case I've overridden the getName() method to dynamically determine the element name. If characteristic property is set, its value will be used as the name, otherwise the method opts to the default characteristic element.

Don't want to miss updates? Please click the below button!

Follow MindStick