0

正如标题所说,我有两个实现相同接口的不同对象,我想将它们添加到同一个集合中。

我的 XML 看起来像:

  <root>
   <item-list>
     <item>
         <type1>
            <id>1</id>
        </type1>
    </item>
    <item>
        <type2>
            <id>2</id>
            <other>1</other>
        </type2>
    </item>
  </item-list>      
</root>

下面的标签item可以是type1type2随时。它们具有相似的值,但如您所见,它们type2具有另一个字段。

我的界面是:

  public interface Item {

   public String getID();
}

我的三门课:

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

我的绑定看起来像这样:

<binding direction="input" >

<mapping name="item-list" class="jibx.woe.MyObj" >

    <collection field="items" >
        <structure name="item" choice="true" ordered="false">

            <structure name="type1" map-as="type1"/>

            <structure name="type2" map-as="type2"/>

        </structure>

    </collection>

</mapping>
<mapping class="jibx.woe.Type1" abstract="true" type-name="type1">
    <value name="id" field="id"/>
</mapping>

<mapping class="jibx.woe.Type2" abstract="true" type-name="type2">
    <value name="id" field="id"/>
    <value name="other" field="other"/>
</mapping>

当我运行它时,我得到了这个错误:

*** Error during code generation for file 'C:\Projects\IdeaProjects\jibx-woe\src \main\config\woe-binding.xml' -
 this may be due to an error in your binding or classpath, or to an error in the JiBX   code ***

 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

所以我想我向集合添加一个项目类型,所以现在我的集合部分看起来像:

   <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>

现在错误说:

  Internal error: Expected jibx.woe.Type1 on stack, found jibx.woe.Item
  full stack:
    0: jibx.woe.Item
    1: jibx.woe.Item
    2: org.jibx.runtime.impl.UnmarshallingContext

所以现在我将以下方法添加到MyObj

  public void addItem(Object type) {
      items.add((Item)type);
   }

并将collection标签更改为:

  <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

现在我没有主意了。我怎样才能让它工作?

编辑

根据 Archie 在下面的建议,我将绑定更改为:

<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

在我上面的第二行。如果我打印对象: System.out.println(items.get(0));

它说:java.lang.Object@1be2d65

所以它是一个普通的对象,根本不是 Element 或 Type1(或 Type2)!

我确实尝试了 Archie 提出的“扩展”方法,但它并没有改变任何东西——我得到了相同的结果。

4

1 回答 1

1

为 Item 创建一个抽象映射。然后为 Type1 和 Type2 创建两个具体映射,每个映射都扩展了 Item 映射。在您的项目集合中,使每个元素成为项目(摆脱选择的东西)。

请注意,在 JiBX 中,“extends”关键字与 Java 类无关,它表示“可以替换”。

限制:您必须为 Type1 和 Type2 提供两个不同的 XML 标记名称(例如,“type1”和“type2”),以便 JiBX 在解组时能够区分它们。这是您当前正在做的事情的问题。例如,当 JiBX 看到一个标签时,它如何知道要实例化哪个 Java 类?

于 2010-08-30T14:52:46.907 回答