JAXB è una specifica, implementazioni specifiche forniranno punti di estensione per fare cose come questa. Se si utilizza EclipseLink JAXB (MOXy) si potrebbe modificare la classe Shape come segue:
import javax.xml.bind.annotation.XmlAttribute;
import org.eclipse.persistence.oxm.annotations.XmlCustomizer;
@XmlCustomizer(ShapeCustomizer.class)
public abstract class Shape {
int points;
@XmlAttribute
public int getPoints() {
return points;
}
public void setPoints(int points) {
this.points = points;
}
}
Poi utilizzando il Moxy @XMLCustomizer si poteva accedere al InheritancePolicy e modificare il campo indica la classe da "@xsi: tipo" a "tipo" solo :
import org.eclipse.persistence.config.DescriptorCustomizer;
import org.eclipse.persistence.descriptors.ClassDescriptor;
public class ShapeCustomizer implements DescriptorCustomizer {
@Override
public void customize(ClassDescriptor descriptor) throws Exception {
descriptor.getInheritancePolicy().setClassIndicatorFieldName("@type");
}
}
sarà necessario assicurarsi di avere un file di jaxb.properties con voi classi del modello (forma, Piazza, ecc) con la seguente voce specificando l'attuazione EclipseLink Moxy JAXB:
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
Di seguito il resto delle classi del modello:
forme
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Shapes {
private List<Shape> shape = new ArrayList<Shape>();;
public List<Shape> getShape() {
return shape;
}
public void setShape(List<Shape> shape) {
this.shape = shape;
}
}
Piazza
import javax.xml.bind.annotation.XmlAttribute;
public class Square extends Shape {
private String squareSpecificAttribute;
@XmlAttribute(name="square-specific-attribute")
public String getSquareSpecificAttribute() {
return squareSpecificAttribute;
}
public void setSquareSpecificAttribute(String s) {
this.squareSpecificAttribute = s;
}
}
Triangolo
import javax.xml.bind.annotation.XmlAttribute;
public class Triangle extends Shape {
private String triangleSpecificAttribute;
@XmlAttribute(name="triangle-specific-attribute")
public String getTriangleSpecificAttribute() {
return triangleSpecificAttribute;
}
public void setTriangleSpecificAttribute(String t) {
this.triangleSpecificAttribute = t;
}
}
Qui di seguito è un programma demo per verificare che tutto funzioni :
import java.io.StringReader;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jaxbContext = JAXBContext.newInstance(Shapes.class, Triangle.class, Square.class);
StringReader xml = new StringReader("<shapes><shape square-specific-attribute='square stuff' type='square'><points>4</points></shape><shape triangle-specific-attribute='triangle stuff' type='triangle'><points>3</points></shape></shapes>");
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
Shapes root = (Shapes) unmarshaller.unmarshal(xml);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(root, System.out);
}
}
Spero che questo aiuti.
Per ulteriori informazioni su EclipseLink Moxy vedere:
EDIT
In EclipseLink 2.2 stiamo rendendo questo più facile da configurare, controllare il seguente articolo per ulteriori informazioni:
Sono decisamente interessato a questo come soluzione, ma non riesco a farlo funzionare. È importante che Shape non sia effettivamente il mio elemento principale? Se provo a rimuovere unmarshall, la raccolta JAXB/MOXy non sembra preoccuparsi di utilizzare il Customizer e genera un sacco di errori nel tentativo di creare un'istanza di una classe astratta. C'è un altro pezzo che mi manca? – Frothy
Credo che manchi il file jaxb.properties che specifica EclipseLink MOXy come implementazione JAXB. Ho aggiornato l'esempio precedente per essere più completo. –
Sei incredibile! Questo funziona perfettamente. Grazie per andare al di sopra e al di là di aiutarmi con questo. – Frothy