2013-06-12 14 views
1

请注意:我处于NDA之下,因此我必须使用不合理的变量名称。对不起如何遍历不同对象的列表?

您好! 我有一个抽象类:

public abstract class A { 

    public abstract List<String> someMethod(); 

} 

和两个类扩展该抽象类:

@Data 
@EqualsAndHashCode(callSuper = true) 
@ToString(callSuper = true) 
@XmlRootElement(name = "BField") 
@XmlAccessorType(XmlAccessType.FIELD) 
public class B extends A { 
... 
} 

@Data 
@EqualsAndHashCode(callSuper = true) 
@ToString(callSuper = true) 
@XmlRootElement(name = "CField") 
@XmlAccessorType(XmlAccessType.FIELD) 
public class C extends A { 
... 
} 

然后在某个地方的代码中还有一类,使这两个类的列表。几乎是这个样子的:

@XmlElementWrapper(name = "MyStuffData") 
    @XmlAnyElement(lax = true) 
    @XmlElementRefs({ 
      @XmlElementRef(name = "B", type = B.class), 
      @XmlElementRef(name = "C", type = C.class), 
    }) 
    private List<A> myStuff; 

myStuff内容可以是B或C吧?我如何遍历该列表?我从肥皂请求中获取数据,所以我只是很困惑如何做到这一点。我想:

for(A a: myStuff){ 
     ...some code here... 
} 

但是我得到这个异常:

Caused by: java.lang.ClassCastException: org.apache.xerces.dom.ElementNSImpl cannot be cast to some.package.here.A 

听说不严=真能解决问题,但我仍然得到同样的错误。令人费解的是,我可以获得相当准确的列表大小,但之后我无法遍历它。任何帮助,将不胜感激。 对不起,我不擅长解释,所以在谷歌找到这种东西是有点痛苦。

回答

0

得到B/C对于你不应该使用这种@XmlAnyElement(lax=true)用例。


使用案例#1 - @XmlElementRef

当使用@XmlElementRef您需要确保在@XmlElementRef注释的元素名称相匹配的@XmlRootElement(或@XmlElementDecl )完全注释。

输入。XML

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <MyStuffData> 
     <BField/> 
     <CField/> 
     <BField/> 
    </MyStuffData> 
</root> 

import java.util.List; 
import javax.xml.bind.annotation.*; 

@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Root { 

    @XmlElementWrapper(name = "MyStuffData") 
    @XmlElementRefs({ 
      @XmlElementRef(name = "BField", type = B.class), 
      @XmlElementRef(name = "CField", type = C.class), 
    }) 
    private List<A> myStuff; 

    public List<A> getMyStuff() { 
     return myStuff; 
    } 

} 

使用案例#2 - @XmlElements

如果你不希望有该元素的名称一样的根您可以使用@XmlElements批注的参考类型的元素名称。

的input.xml

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <MyStuffData> 
     <B/> 
     <C/> 
     <B/> 
    </MyStuffData> 
</root> 

import java.util.List; 
import javax.xml.bind.annotation.*; 

@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Root { 

    @XmlElementWrapper(name = "MyStuffData") 
    @XmlElements({ 
      @XmlElement(name = "B", type = B.class), 
      @XmlElement(name = "C", type = C.class), 
    }) 
    private List<A> myStuff; 

    public List<A> getMyStuff() { 
     return myStuff; 
    } 

} 

COMMON

以下是两种用例的常见情况。

public abstract class A { 
} 

import javax.xml.bind.annotation.*; 

@XmlRootElement(name = "BField") 
public class B extends A { 
} 

Ç

import javax.xml.bind.annotation.*; 

@XmlRootElement(name = "CField") 
public class C extends A { 
} 

演示

import java.io.File; 
import javax.xml.bind.*; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(Root.class); 

     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     File xml = new File("src/forum17061559/input.xml"); 
     Root root = (Root) unmarshaller.unmarshal(xml); 

     for(A a : root.getMyStuff()) { 
      System.out.println(a); 
     } 
    } 

} 

输出

[email protected] 
[email protected] 
[email protected] 
0

貌似myStuff其实不是List<A>(或List<B>),但是,List<ElementNSImpl>,其中org.apache.xerces.dom.ElementNSImpl实例似乎是某种包装过的BC实际的实例。

您可以调试该列表,并尝试看看你能不能从org.apache.xerces.dom.ElementNSImpl

+0

@ joannaSmith12我明白,现场离岸队:( – anshulkatta