JAXB

2011-03-12 13 views
2
内の要素間の参照を処理する方法を

は、次の問題があり、私は同様のクラス構造を持っています。このクラスのJAXB

class A { 
public String a; 
} 

class B extends A { 
public String b; 
} 

class C { 
    public List<A> alist; 
    public A current; 
} 

構造を変更することはできません。私。 id属性を追加できません。 これらのクラスのxsdスキーマを作成する必要があります。 current要素は、alist要素の1つです。 だから私はここでいくつかの種類の参照が欲しい。しかし、私はどのように@XmlID@XmlIREFを使用することはできません。 次に、スキーマXMLファイルのベースが生成され、JAXB経由でオブジェクトにロードされます。 これを行う方法はありますか? JAXBが理解できるxpointerなどを何とか使うことができますか?

+0

一意の識別子「A」クラスの「」プロパティですか? –

+0

いいえ、それは一意ではありません。なんらかの種類のxpathポインタを持つことは素晴らしいことです。 2番目の要素をalistから取り出して現在に適用する – Egor

+0

Cはルートオブジェクトですか? –

答えて

2

[OK]を、私はこのようなソリューションで終わる:

RuntimeAnnotationReaderのカスタムのimplを使用して、私は2つの連想リストするadaterの種類や現在の要素を埋め込みます。

ABeanWrapperは、2つのフィールドが含まれ
public class ABeanAdapterList extends XmlAdapter<ABeanWrapper, Abean> { 

    public int i = 0; 

    private Map<Abean, String> unmarshall = new HashMap<Abean, String>(); 
    private Map<String, Abean> marshall = new HashMap<String, Abean>(); 


    @Override 
    public Abean unmarshal(ABeanWrapper v) throws Exception { 
     marshall.put(v.id, v.abean); 
     return v.abean; 
    } 

    @Override 
    public ABeanWrapper marshal(Abean v) throws Exception { 
     ABeanWrapper beanWrapper = new ABeanWrapper(); 
     beanWrapper.abean = v; 
     beanWrapper.id = String.valueOf(i++); 
     unmarshall.put(beanWrapper.abean , beanWrapper.id); 
     return beanWrapper; 
    } 

    public String getId(Abean abean) { 
     return unmarshall.get(abean); 
    } 

    public Abean getAbean(String id) { 
     return marshall.get(id); 
    } 
} 

:連想リストのために、現在のidとABean :

public class ABeanAdapterImpl extends XmlAdapter<ABeanRef, Abean> { 

     private ABeanAdapterList listAdapter; 

     public ABeanAdapterImpl(ABeanAdapterList list) { 
      listAdapter = list; 
     } 

     @Override 
     public Abean unmarshal(ABeanRef wrapper) throws Exception { 
      return listAdapter.getAbean(wrapper.refId); 
     } 

     @Override 
     public ABeanRef marshal(Abean abean) throws Exception { 
      ABeanRef ref = new ABeanRef(); 
      ref.refId = listAdapter.getId(abean); 
      return ref; 

     } 
    } 

をそしてABeanRefが一つだけのREFフィールドが含まれています。 はそのような方法起動しますが、より良い方法があるが、このアプローチが機能することにより、

Marshaller marshaller = context.createMarshaller(); 
ABeanAdapterList adapterList = new ABeanAdapterList(); 
marshaller.setAdapter(adapterList); 
ABeanAdapterImpl beanAdapter = new ABeanAdapterImpl(adapterList); 
marshaller.setAdapter(beanAdapter); 
marshaller.marshal(sBean, new File("testSBean.xml")); 

月...