Java 如何让Jibx在集合中添加两个实现同一接口的不同对象?
正如标题所说,我有两个实现相同接口的不同对象,我想将它们添加到同一个集合中 我的XML看起来像:Java 如何让Jibx在集合中添加两个实现同一接口的不同对象?,java,xml,jibx,Java,Xml,Jibx,正如标题所说,我有两个实现相同接口的不同对象,我想将它们添加到同一个集合中 我的XML看起来像: <root> <item-list> <item> <type1> <id>1</id> </type1> </item> <item> <type2>
<root>
<item-list>
<item>
<type1>
<id>1</id>
</type1>
</item>
<item>
<type2>
<id>2</id>
<other>1</other>
</type2>
</item>
</item-list>
</root>
<collection field="items" item-type="jibx.woe.Item">
<structure name="item" choice="true" ordered="false" >
<structure name="type1" map-as="type1"/>
<structure name="type2" map-as="type2"/>
</structure>
</collection>
我的三门课:
public class MyObj {
private ArrayList<Item> items = new ArrayList<Item>();
public List<Item> getItems() {
return items;
}
}
public class Type1 implements Item{
private String id;
@Override
public String getID() {
return id;
}
}
public class Type2 implements Item {
private String id;
private String other;
@Override
public String getID() {
return id;
}
public String getOther() {
return other;
}
}
因此,我认为我向集合中添加了一个项目类型,因此现在我的集合部分如下所示:
<root>
<item-list>
<item>
<type1>
<id>1</id>
</type1>
</item>
<item>
<type2>
<id>2</id>
<other>1</other>
</type2>
</item>
</item-list>
</root>
<collection field="items" item-type="jibx.woe.Item">
<structure name="item" choice="true" ordered="false" >
<structure name="type1" map-as="type1"/>
<structure name="type2" map-as="type2"/>
</structure>
</collection>
因此,现在我将以下方法添加到MyObj
:
public void addItem(Object type) {
items.add((Item)type);
}
并将集合
标记更改为:
<collection add-method="addItem">
现在我没有主意了。我怎样才能让它工作
编辑
根据以下阿尔奇的建议,我将我的绑定更改为:
<mapping name="root" class="jibx.woe.MyObj">
<structure name="item-list" >
<collection field="items">
<structure name="item" /> >
</collection>
</structure>
</mapping>
<mapping name="type1" class="jibx.woe.Type1" >
<value name="id" field="id"/>
</mapping>
<mapping name="type2" class="jibx.woe.Type2" >
<value name="id" field="id"/>
<value name="other" field="other"/>
</mapping>
</binding>
在我上面的第二行。如果我打印对象:
System.out.println(items.get(0))
它说:
java.lang。Object@1be2d65
所以它是一个普通的对象,而不是元素或类型1(或类型2)
我确实尝试了阿尔奇提出的“扩展”方法,但它没有改变任何东西——我得到了相同的结果。为项创建一个抽象映射。然后为Type1和Type2创建两个具体的映射,每个映射都扩展了项映射。在items集合中,将每个元素都设置为Item(去掉choice元素) 注意,在JiBX中,“extenses”关键字与Java类无关,它表示“可以替换”
限制:您必须给Type1和Type2两个不同的XML标记名(例如,“Type1”和“Type2”),以便JiBX在解组时能够区分它们。这就是您当前所做工作的问题所在。例如,当JiBX看到一个标记时,它如何知道要实例化哪个Java类?不是很确定,但尝试用ListMohammad替换List:我没有想到,但它也不起作用。请参见上面的输出。我们现在如此接近。我对正在解析的XML也几乎没有控制权,所以我需要弄清楚如何使用上面的结构进行解析。但我同意——我的风格并没有让这更容易。
<collection add-method="addItem">
Internal error: Expected jibx.woe.Type1 on stack, found java.lang.Object
full stack:
0: java.lang.Object
1: java.lang.Object
2: org.jibx.runtime.impl.UnmarshallingContext
<mapping name="root" class="jibx.woe.MyObj">
<structure name="item-list" >
<collection field="items">
<structure name="item" /> >
</collection>
</structure>
</mapping>
<mapping name="type1" class="jibx.woe.Type1" >
<value name="id" field="id"/>
</mapping>
<mapping name="type2" class="jibx.woe.Type2" >
<value name="id" field="id"/>
<value name="other" field="other"/>
</mapping>
</binding>
List<Item> items = woe.getItems();
Type1 item = (Type1) items.get(0);
java.lang.ClassCastException: java.lang.Object cannot be cast to jibx.woe.Type1