JAXB là một triển khai cụ thể, cụ thể sẽ cung cấp các điểm mở rộng để thực hiện những việc như vậy. Nếu bạn đang sử dụng EclipseLink JAXB (MOXy) bạn có thể sửa đổi các lớp Shape như sau:
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;
}
}
Sau đó, bằng cách sử dụng MOXY @XMLCustomizer bạn có thể truy cập vào InheritancePolicy và thay đổi lĩnh vực chỉ số lớp từ "@xsi: gõ" để chỉ "gõ" :
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");
}
}
bạn sẽ cần phải đảm bảo rằng bạn có nộp jaxb.properties với bạn lớp mô hình (Shape, Square, vv) với các mục sau đây quy định cụ thể việc thực hiện EclipseLink MOXY JAXB:
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
Dưới đây là phần còn lại của các lớp mô hình:
Shapes
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;
}
}
Quảng trường
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;
}
}
Triangle
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;
}
}
Dưới đây là một chương trình demo để kiểm tra xem mọi thứ suôn sẻ :
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);
}
}
Tôi hy vọng điều này sẽ hữu ích.
Để biết thêm thông tin về EclipseLink MOXY xem:
EDIT
Trong EclipseLink 2.2 chúng tôi đang làm cho dễ dàng hơn này để cấu hình, hãy kiểm tra bài viết sau để biết thêm thông tin:
Tôi chắc chắn quan tâm đến điều này như một giải pháp, nhưng tôi dường như không thể làm cho nó hoạt động được. Liệu hình dạng có thực sự không phải là phần tử gốc của tôi không? Nếu tôi cố gắng và unmarshall bộ sưu tập JAXB/MOXy dường như không bận tâm bằng cách sử dụng Customizer và ném một loạt các lỗi về cố gắng để nhanh chóng một lớp trừu tượng. Tôi còn thiếu một phần khác không? – Frothy
Tôi tin rằng bạn đang thiếu tệp jaxb.properties chỉ định EclipseLink MOXy là triển khai JAXB. Tôi đã cập nhật ví dụ trên để hoàn chỉnh hơn. –
Bạn thật tuyệt vời! Điều này hoạt động hoàn hảo. Cảm ơn bạn đã đi xa hơn và hơn thế nữa để giúp tôi với điều này. – Frothy