JAXB es una especificación, las implementaciones específicas proporcionarán puntos de extensión para hacer cosas como esta. Si está utilizando EclipseLink JAXB (MOXy) podría modificar la clase Shape de la siguiente manera:
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;
}
}
Luego, utilizando el moxy @XMLCustomizer se podía acceder al InheritancePolicy y cambie el campo Indicador de la clase de "@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");
}
}
usted tendrá que asegurarse de que tiene un archivo de jaxb.properties contigo clases del modelo (forma, cuadrado, etc.) con la siguiente entrada especifica la aplicación EclipseLink moxy JAXB:
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
A continuación se muestra el resto de las clases del modelo:
Formas
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;
}
}
Plaza
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;
}
}
Triángulo
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;
}
}
A continuación se muestra un programa de demostración para comprobar que todo funciona :
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);
}
}
Espero que esto ayude.
Para obtener más información sobre EclipseLink moxy ver:
EDITAR
En EclipseLink 2.2 estamos haciendo esto más fácil de configurar, revisa el siguiente artículo para Más información:
Definitivamente estoy interesado en esto como una solución, pero parece que no puedo hacer que funcione. ¿Importa que Shape no sea en realidad mi elemento raíz? Si trato de deshacerme de la colección JAXB/MOXy no parece molestarme con el personalizador y arroja un montón de errores sobre intentar crear una instancia de una clase abstracta. ¿Hay alguna otra pieza que me falta? – Frothy
Creo que le falta el archivo jaxb.properties que especifica EclipseLink MOXy como la implementación de JAXB. He actualizado el ejemplo anterior para que sea más completo. –
¡Eres increíble! Esto funciona perfectamente Gracias por ir más allá para ayudarme con esto. – Frothy