How can I create a class field using the name JAXB?

I use Java and JAXB to process XML.

I have the following class:

public class Characteristic {

    private String characteristic;
    private String value;

    @XmlAttribute
    public String getCharacteristic() {
        return characteristic;
    }

    public void setCharacteristic(String characteristic) {
        this.characteristic = characteristic;
    }

    @XmlValue
    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

public static void main(String[] args) {
    Characteristic c = new Characteristic();
    c.setCharacteristic("store_capacity");
    c.setValue(40);
    Characteristic c2 = new Characteristic();
    c2.setCharacteristic("number_of_doors");
    c2.setValue(4);
}

As a result, I get:

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

I want to get the following result:

<store_capacity>40</store_capacity>
<number_of_doors>4</number_of_doors>

How can i achieve this?

+4
source share
4 answers

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

The idea is this:

  • Make Characteristica subclass JAXBElementand override the method getName()to return the name of the properties of the basis Characteristic.
  • Annotate characteristicswith @XmlElementRef.
  • Provide @XmlRegistry( ObjectFactory) @XmlElementDecl(name = "characteristic").

.

( ):

@Test
public void marshallsDynamicElementName() throws JAXBException {
    JAXBContext context = JAXBContext.newInstance(ObjectFactory.class);
    final Characteristics characteristics = new Characteristics();
    final Characteristic characteristic = new Characteristic(
            "store_capacity", "40");
    characteristics.getCharacteristics().add(characteristic);
    context.createMarshaller().marshal(characteristics, System.out);
}

:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<characteristics><store_capacity>40</store_capacity></characteristics>

characteristics. characteristics, @XmlElementRef. , JAXBElement, @XmlRootElement - .

@XmlRootElement(name = "characteristics")
public class Characteristics {

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

    @XmlElementRef(name = "characteristic")
    public List<Characteristic> getCharacteristics() {
        return characteristics;
    }

}

ObjectFactory - @XmlRegistry @XmlElementDecl:

@XmlRegistry
public class ObjectFactory {

    @XmlElementDecl(name = "characteristic")
    public JAXBElement<String> createCharacteristic(String value) {
        return new Characteristic(value);
    }

}

, characteristics @XmlRootElement - , JAXBElement s. @XmlRootElement , . JAXBElement . JAXBElement getName():

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

    @Override
    public QName getName() {
        final String characteristic = getCharacteristic();
        if (characteristic != null) {
            return new QName(characteristic);
        }
        return super.getName();
    }

    private String characteristic;

    @XmlTransient
    public String getCharacteristic() {
        return characteristic;
    }

    public void setCharacteristic(String characteristic) {
        this.characteristic = characteristic;
    }
}

getName() . Characteristic, , Characteristic .

GitHub.

+2

EclipseLink MOXy JAXB (JSR-222), @XmlVariableNode (. <2 > ):

Java

@XmlVariableNode . / , .

import java.util.List;
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlVariableNode;

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

    @XmlVariableNode("characteristic")
    private List<Characteristic> characteristics;

}

characteristic @XmlTransient, .

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
public class Characteristic {

    @XmlTransient
    private String characteristic;

    @XmlValue
    private String value;

}

jaxb.properties

MOXy JAXB, EclipseLink jaxb.properties , (. <3 > ).

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

-

Demo

- -, / XML. , API JAXB.

import java.io.File;
import javax.xml.bind.*;

public class Demo {

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

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("input.xml");
        Characteristics characteristics = (Characteristics) unmarshaller.unmarshal(xml);

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

}

Input.xml/

<?xml version="1.0" encoding="UTF-8"?>
<characteristics>
   <store_capacity>40</store_capacity>
   <number_of_doors>4</number_of_doors>
</characteristics>
+2

JAXB (JSR-222).

Java

XmlAnyElement. , , DOM. XmlAdapter Characteristic DOM.

import java.util.List;
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

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

    @XmlAnyElement
    @XmlJavaTypeAdapter(CharacteristicAdapter.class)
    private List<Characteristic> characteristics;

}

JAXB, .

public class Characteristic {

    String characteristic;

    String value;

}

CharacteristicAdapter

XmlAdapter Characteristic DOM node , , .

import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.*;

public class CharacteristicAdapter extends XmlAdapter<Object, Characteristic> {

    private Document doc;

    public CharacteristicAdapter() {
        try {
        doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        } catch(Exception e) {
            throw new RuntimeException(e);
        }
    }


    @Override
    public Characteristic unmarshal(Object v) throws Exception {
        Element element = (Element) v;
        Characteristic characteristic = new Characteristic();
        characteristic.characteristic = element.getLocalName();
        characteristic.value = element.getTextContent();
        return characteristic;
    }

    @Override
    public Object marshal(Characteristic v) throws Exception {
        Element element = doc.createElement(v.characteristic);
        element.setTextContent(v.value);
        return element;
    }

}

-

Demo

, / XML. , setAdapter Marshaller , , XmlAdapter.

import java.io.File;
import javax.xml.bind.*;

public class Demo {

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

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("input.xml");
        Characteristics characteristics = (Characteristics) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.setAdapter(new CharacteristicAdapter());
        marshaller.marshal(characteristics, System.out);
    }

}

Input.xml/

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<characteristics>
    <store_capacity>40</store_capacity>
    <number_of_doors>4</number_of_doors>
</characteristics>
+1

you can specify your class as:

@XmlRootElement(name = "Characteristic")
public class Characteristic {


    @XmlElement(name = "store_capacity")
    protected String storeCapacity;


    @XmlElement(name = "number_of_doors")
    protected String numberOfDoors;

    /** getters and setters of above attributes **/
}

EDIT . If you want the attributes to be dynamic, you can link below to the link

getting dynamic attribute for item in jaxb

0
source

All Articles