2013-04-12 111 views
2

好吧,這裏是當我做下面會發生什麼:@XmlJavaTypeAdapter,繼承和XSI:類型

Entities.java:所有這些類的名字開始與「E」(例如EStudent,ETeacher等)的延伸EntityWithId類。

public class Entities { 

    Map<Integer,EStudent> students; 
    Map<Integer,ETeacher> teachers; 
    Map<Integer,ECourse> courses; 
    Map<Integer,EQuiz> quizzes; 
    Map<Integer,EQuestion> questions; 
    Map<Integer,EAnswer> answers; 
    Map<Integer,ETimeslot> timeslots; 
    Map<Integer,ESharedFile> sharedFiles; 

    ... 
} 

entities-xml-bindings.xml:我爲所有屬性設置了xml-java-type-adapter。爲了清楚起見,省略。

<?xml version="1.0" encoding="US-ASCII"?> 
    <xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm" 
    package-name="com.pest.esinif.common.entity"> 

<java-types> 
    <java-type name="Entities"> 
     <java-attributes> 
      <xml-element java-attribute="students" > 
       <xml-java-type-adapter value="com.pest.esinif.common.entity.adapters.MapToCollectionAdapter" /> 
      </xml-element> 
      ... 
     </java-attributes> 
    </java-type> 
</java-types> 
</xml-bindings> 

MapToCollectionAdapter.java:有意地圖轉換成集合。

public class MapToCollectionAdapter extends XmlAdapter<MyCollection, Map<Integer,EntityWithId>> { 

@Override 
public Map<Integer, EntityWithId> unmarshal(MyCollection v) throws Exception { 
    Map<Integer, EntityWithId> m = new TreeMap<>(); 

    for (Iterator<EntityWithId> it = v.list.iterator(); it.hasNext();) { 
     EntityWithId i = it.next(); 
     m.put(i.getId(), i); 
    } 

    return m; 
} 

@Override 
public MyCollection marshal(Map<Integer, EntityWithId> v) throws Exception { 
    if(v == null) { 
     return null; 
    } 
    MyCollection mc = new MyCollection(); 
    mc.list = v.values(); 
    return mc; 
} 

class MyCollection { 

    @XmlElement(name="entry") 
    public Collection<EntityWithId> list; 

    public MyCollection() {} 
} 

當我編組此,輸出是如下。

<?xml version="1.0" encoding="UTF-8"?> 
<entities> 
    <courses> 
     <entry id="4" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="eCourse"> 
     <name>English</name> 
     <timetable>5</timetable> 
     <timetable>6</timetable> 
     </entry> 
    </courses> 
    <students> 
     <entry id="1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="eStudent"> 
     <name>Anil Anar</name> 
     </entry> 
    </students> 
    <timeslots> 
     <entry id="12" course="4" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="eTimeslot"> 
     <attendances>1</attendances> 
     <day>1970-01-01T02:00:00.0</day> 
     <slot>0</slot> 
     </entry> 
    </timeslots> 
</entities> 

你有沒有注意到那些xsi:type S'當我忽略它們時,unmarshaller顯然失敗了。但我不希望所有<entry>標籤有。我更喜歡它如下:

<courses child-xsi-type="eCourse"> 
    <entry> ... </entry> 
    <entry> ... </entry> 
</courses> 

感謝您的幫助。

+0

這個問題似乎是它涉及到我的,但它的答案是不夠明確:http://stackoverflow.com/questions/8912925/jaxb-elipselink-xmljavatypeadapter -and-的型屬性?RQ = 1 – mostruash

回答

0

我解決了這個問題由於Blaise Doughan's blogs。訣竅是使用@XmlAnyElement(lax=true),並註釋的EntityWithId子類與@XmlRootElement

class MyCollection { 

    @XmlAnyElement(lax=true) 
    public Collection<EntityWithId> list; 

    public MyCollection() {} 
} 

輸出我得到:

<?xml version="1.0" encoding="UTF-8"?> 
<entities> 
    <courses> 
     <course id="4"> 
     <name>English</name> 
     <timetable>5</timetable> 
     <timetable>6</timetable> 
     </course> 
    </courses> 
    <students> 
     <student id="1"> 
     <name>Anil Anar</name> 
     </student> 
    </students> 
    <timeslots> 
     <timeslot id="12"> 
     <attendances>1</attendances> 
     <day>1970-01-01T02:00:00.0</day> 
     <slot>0</slot> 
     </timeslot> 
    </timeslots> 
</entities>