如何处理JAXB中元素之间的引用

时间:2011-03-12 16:36:51

标签: java 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元素的元素。 所以我想在这里提供一些参考资料。但我不知道如何使用@XmlID@XmlIREF。 然后将基于模式xml文件生成并通过JAXB加载到对象。 有没有办法做到这一点?可能以某种方式使用xpointer或其他任何东西,JAXB可以理解吗?

1 个答案:

答案 0 :(得分:2)

好的,我最终得到了这样的解决方案:

使用RuntimeAnnotationReader的自定义impl,我将两种类型的adater嵌入alist和current元素。

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);
    }
}

其中ABeanWrapper包含两个字段:id和ABean 对于alist和当前:

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"));

可能有更好的方法,但这种方法有效......