2011-09-30 58 views
3

在解組過程中,是否可以在JAXB XmlAdapter中處理XML IDREF元素的前向引用?例如,我有以下XML complexType如何在解組期間處理帶有JAXB XmlAdapter的XML IDREF的向前引用?

<xs:complexType name="person"> 
    <xs:complexContent> 
     <xs:sequence> 
      <xs:element name="dateOfBirth" type="xs:dateTime" minOccurs="0"/> 
      <xs:element name="firstName" type="xs:string" minOccurs="0"/> 
      <xs:element name="gender" type="xs:string" minOccurs="0"/> 
      <xs:element name="guardian" type="xs:IDREF" minOccurs="0"/> 
      <xs:element name="homePhone" type="xs:string" minOccurs="0"/> 
      <xs:element name="lastName" type="xs:string" minOccurs="0"/> 
     </xs:sequence> 
    </xs:complexContent> 
</xs:complexType> 

其中guardian字段可以在文檔的其它地方引用另一個Person型元件。目前,我正在使用XmlAdapter進行編組,以便在第一次編組對象時,通過包容進行編組,並且此對象的任何後續出現都通過引用進行編組。查看以前的mine問題。但是,由於我的XML實例文檔的創建方式,Person元素的第一次出現可能會在IDREF發生之後發生。

這是可能的東西嗎?或者我需要以不同的方式處理?謝謝!

回答

6

我有一個答案,你的related question我概括的XmlAdapter如何被用來實施對象的第一次出現是通過遏制/嵌套和所有其他事件被引用整理整理用例:

選項#1 - @XmlID/@XmlIDREF

如果所有Person對象都是通過嵌套表示的,並且您希望引入一些基於關鍵的關係,那麼您最好使用@XmlID將字段/屬性標記爲關鍵字,並且@XmlID將字段/屬性映射爲外鍵鍵。你Person類看起來是這樣的:

@XmlAccessorType(XmlAccessType.FIELD) 
public class Person { 

    @XmlID 
    private String id; 

    @XmlIDREF 
    private Person guardian; 
} 

更多信息

選項#2 - 使用XmlAdapter

如果您更新從XmlAdapterprevious answer爲:

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) { 
      if(adaptedPhoneNumber.number != null) { 
       phoneNumber.setNumber(adaptedPhoneNumber.number); 
      } 
      return phoneNumber; 
     } 
     phoneNumber = adaptedPhoneNumber.getPhoneNumber(); 
     phoneNumberMap.put(phoneNumber.getId(), phoneNumber); 
     return phoneNumber; 
    } 

} 

然後你就可以看起來像下面的解組XML文檔,其中基準首先發生:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<customer> 
    <phone-number id="A"/> 
    <phone-number id="B"> 
     <number>555-BBBB</number> 
    </phone-number> 
    <phone-number id="A"> 
     <number>555-AAAA</number> 
    </phone-number> 
    <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> 
+0

這是'選項1'&'選項2'或'一步1'&'第2步? – Tony