JAXB最初可以通过收容进行封送,然后通过@XmlIDREF封送后续引用吗
我想知道是否有可能对我的类进行注释,以便第一次编组遇到一个对象,它会生成一个相应类型的
XML元素,但是任何后续对该对象的任何引用都会创建一个XML IDREF条目?
您可以利用JAXB的XmlAdapter概念执行以下操作:
input.xml中 以下是我将用于此示例的XML文档.第3个电话号码条目是对第1个电话号码条目的引用,第5个电话号码条目是对第4个的电话号码条目的引用: <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <customer> <phone-number id="A"> <number>555-AAAA</number> </phone-number> <phone-number id="B"> <number>555-BBBB</number> </phone-number> <phone-number id="A"/> <phone-number xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="work-phone-number" id="W"> <number>555-WORK</number> <extension>1234</extension> </phone-number> <phone-number xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="work-phone-number" id="W"/> </customer> 顾客 customer类维护一组PhoneNumber对象. PhoneNumber的相同实例可能会在集合中多次出现. package forum7587095; import java.util.List; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class Customer { private List<PhoneNumber> phoneNumbers; @XmlElement(name="phone-number") public List<PhoneNumber> getPhoneNumbers() { return phoneNumbers; } public void setPhoneNumbers(List<PhoneNumber> phoneNumbers) { this.phoneNumbers = phoneNumbers; } } 电话号码 这是一个可以出现在文档本身或作为参考的类.这将使用XmlAdapter处理.使用@XmlJavaTypeAdapter批注配置XmlAdapter.由于我们在类型/类级别指定了此适配器,因此它将应用于引用PhoneNumber类的所有属性: package forum7587095; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; @XmlJavaTypeAdapter(PhoneNumberAdapter.class) public class PhoneNumber { private String id; private String number; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } @Override public boolean equals(Object arg0) { if(null == arg0 || arg0.getClass() != this.getClass()) { return false; } PhoneNumber test = (PhoneNumber) arg0; if(!equals(id,test.getId())) { return false; } return equals(number,test.getNumber()); } protected boolean equals(String control,String test) { if(null == control) { return null == test; } else { return control.equals(test); } } @Override public int hashCode() { return id.hashCode(); } } WorkPhoneNumber 根据您的评论,我添加了PhoneNumber的子类. package forum7587095; public class WorkPhoneNumber extends PhoneNumber { private String extension; public String getExtension() { return extension; } public void setExtension(String extension) { this.extension = extension; } @Override public boolean equals(Object arg0) { if(!super.equals(arg0)) { return false; } return equals(extension,((WorkPhoneNumber) arg0).getExtension()); } } PhoneNumberAdapter 下面是XmlAdapter的实现.请注意,如果之前看过PhoneNumber对象,我们必须维护.如果有,我们只填充AdaptedPhoneNumber对象的id部分. package forum7587095; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlSeeAlso; import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.adapters.XmlAdapter; public class PhoneNumberAdapter extends XmlAdapter<PhoneNumberAdapter.AdaptedPhoneNumber,PhoneNumber>{ private List<PhoneNumber> phoneNumberList = new ArrayList<PhoneNumber>(); private Map<String,PhoneNumber> phoneNumberMap = new HashMap<String,PhoneNumber>(); @XmlSeeAlso(AdaptedWorkPhoneNumber.class) @XmlType(name="phone-number") public static class AdaptedPhoneNumber { @XmlAttribute public String id; public String number; public AdaptedPhoneNumber() { } public AdaptedPhoneNumber(PhoneNumber phoneNumber) { id = phoneNumber.getId(); number = phoneNumber.getNumber(); } public PhoneNumber getPhoneNumber() { PhoneNumber phoneNumber = new PhoneNumber(); phoneNumber.setId(id); phoneNumber.setNumber(number); return phoneNumber; } } @XmlType(name="work-phone-number") public static class AdaptedWorkPhoneNumber extends AdaptedPhoneNumber { public String extension; public AdaptedWorkPhoneNumber() { } public AdaptedWorkPhoneNumber(WorkPhoneNumber workPhoneNumber) { super(workPhoneNumber); extension = workPhoneNumber.getExtension(); } @Override public WorkPhoneNumber getPhoneNumber() { WorkPhoneNumber phoneNumber = new WorkPhoneNumber(); phoneNumber.setId(id); phoneNumber.setNumber(number); phoneNumber.setExtension(extension); return phoneNumber; } } @Override public AdaptedPhoneNumber marshal(PhoneNumber phoneNumber) throws Exception { AdaptedPhoneNumber adaptedPhoneNumber; if(phoneNumberList.contains(phoneNumber)) { if(phoneNumber instanceof WorkPhoneNumber) { adaptedPhoneNumber = new AdaptedWorkPhoneNumber(); } else { adaptedPhoneNumber = new AdaptedPhoneNumber(); } adaptedPhoneNumber.id = phoneNumber.getId(); } else { if(phoneNumber instanceof WorkPhoneNumber) { adaptedPhoneNumber = new AdaptedWorkPhoneNumber((WorkPhoneNumber)phoneNumber); } else { adaptedPhoneNumber = new AdaptedPhoneNumber(phoneNumber); } phoneNumberList.add(phoneNumber); } return adaptedPhoneNumber; } @Override public PhoneNumber unmarshal(AdaptedPhoneNumber adaptedPhoneNumber) throws Exception { PhoneNumber phoneNumber = phoneNumberMap.get(adaptedPhoneNumber.id); if(null != phoneNumber) { return phoneNumber; } phoneNumber = adaptedPhoneNumber.getPhoneNumber(); phoneNumberMap.put(phoneNumber.getId(),phoneNumber); return phoneNumber; } } 演示 为了确保XmlAdapter的相同实例用于整个编组和解组操作,我们必须在Marshaller和Unmarshaller上专门设置XmlAdapter的实例: package forum7587095; import java.io.File; 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 jc = JAXBContext.newInstance(Customer.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); unmarshaller.setAdapter(new PhoneNumberAdapter()); File xml = new File("src/forum7587095/input.xml"); Customer customer = (Customer) unmarshaller.unmarshal(xml); System.out.println(customer.getPhoneNumbers().get(0) == customer.getPhoneNumbers().get(2)); System.out.println(customer.getPhoneNumbers().get(3) == customer.getPhoneNumbers().get(4)); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,true); marshaller.setAdapter(new PhoneNumberAdapter()); marshaller.marshal(customer,System.out); } } 产量 true true <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <customer> <phone-number id="A"> <number>555-AAAA</number> </phone-number> <phone-number id="B"> <number>555-BBBB</number> </phone-number> <phone-number id="A"/> <phone-number xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="work-phone-number" id="W"> <number>555-WORK</number> <extension>1234</extension> </phone-number> <phone-number xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="work-phone-number" id="W"/> </customer> 欲获得更多信息 > http://blog.bdoughan.com/2011/09/mixing-nesting-and-references-with.html (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |