2011-09-02 83 views
2

鉴于像XSD这一个:JAXB可以使用未知类型的已知元素的基类型吗?

<!-- ... --> 
    <xsd:element name="MyElement" type="ParentType" /> 
<!-- ... --> 
<xsd:complexType name="ParentType"> 
    <xsd:sequence> 
     <!-- ... --> 
     </xsd:sequence> 
</xsd:complexType> 
<xsd:complexType name="ChildType1"> 
    <xsd:complexContent> 
     <xsd:extension base="ParentType"> 
      <xsd:sequence> 
       <!-- ... --> 
      </xsd:sequence> 
     </xsd:extension> 
    </xsd:complexContent> 
</xsd:complexType> 
<!-- ... --> 

可以JAXB2被配置为回退,以当它具有解组包含一个未知的类型的元件,如在接下来的示例的XML基类型ParentType的:

<!-- ... --> 
<MyElement xsi:type="ChildType2"> 
    <!-- ... --> 
</MyElement> 
<!-- ... --> 

通常情况下,在这种情况下,JAXB抛出一个异常,它说,ChildType2是无法识别的类型。

+0

+1 - JAXB可以定义首先在继承层次结构中使用'xsi:type'(http://blog.bdoughan.com/2010/11/jaxb-and-inheritance-using-xsitype.html)。你的问题是如何处理'xsi:type'不对应于JAXB意识到的类的情况? –

+0

是的,Blaise,我的问题是关于xsi:type对应于JAXB不知道的类的情况。 –

回答

2

这不完全符合您的需求,但您可以使用@XmlAnyElement将未知类型解组为DOM元素。

考虑一个Customer类,其中extras字段注解为全部为@XmlAnyElement

@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Customer { 
    @XmlElement 
    private String name; 
    @XmlAnyElement 
    private List<Element> extras = new ArrayList<Element>(); 

    public String getName() { 
     return name; 
    } 

    public List<Element> getExtras() { 
     return extras; 
    } 
} 

示例XML:

<?xml version="1.0" encoding="UTF-8"?> 
<customer> 
    <name>John Doe</name> 
    <salary>1000</salary> 
    <age>45</age> 
</customer> 

SalaryAge是未知类型,并存储在我们的演员名单时,我们解组:

JAXBContext jc = JAXBContext.newInstance(Customer.class); 
Unmarshaller unmarshaller = jc.createUnmarshaller(); 
Customer customer = (Customer) unmarshaller.unmarshal(reader); 
System.out.println(customer.getName()); 
for (Element el : customer.getExtras()) { 
    System.out.println(el.getNodeName() + "->" 
       + el.getTextContent()); 

输出:

John Doe 
salary->1000 
age->45 
+0

+1 - 同样如果你设置了'@XmlAnyElement(lax = true)',那么你的JAXB实现会将已知类型转换为对象形式:http://blog.bdoughan.com/2010/08/using-xmlanyelement-to-build -generic.html –

+0

使用'@ XmlAnyElement'的问题是您必须查看元素列表才能找到所需的元素。例如,就我而言,我希望能够使用JAXB,即使有人用我不知道的新类型更新XML模式,但是这是已知类型的扩展。另外,'@ XmlAnyElement'需要将添加的元素添加到任何未知元素可能出现的位置,我不知道这些位置。我虽然可能会有一些配置选项或选项可以允许这样做。 –