代码之家  ›  专栏  ›  技术社区  ›  MikeHoss

如何让Jibx在一个集合中添加两个实现同一接口的不同对象?

  •  0
  • MikeHoss  · 技术社区  · 14 年前

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

    我的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 type1 type2 任何时候。它们有相似的值,但如你所见, 类型2 有另一个领域。

    我的界面是:

      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
    

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

    编辑

    根据阿奇的建议,我将我的绑定更改为:

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

    现在绑定工作没有堆栈错误(万岁!)但是现在当我从我的单子上得到一个项目时,一个la:

        List<Item> items = woe.getItems();
        Type1 item = (Type1) items.get(0);
    

    我得到:

        java.lang.ClassCastException: java.lang.Object cannot be cast to jibx.woe.Type1
    

    系统输出打印(项目.获取(0));

    上面写着: java.lang.Object对象@1贝德65

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

    1 回复  |  直到 14 年前
        1
  •  1
  •   Archie    14 年前

    为项创建抽象映射。然后为Type1和Type2创建两个具体的映射,每个映射都扩展了项映射。在items集合中,使每个元素都成为Item(去掉choice元素)。

    注意,在JiBX中,“extends”关键字与Java类无关,它的意思是“可以替换”。

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