2011-09-02 1 views
2

donné une XSD comme celui-ci:JAXB peut-il utiliser le type de base pour un élément connu avec un type inconnu?

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

pourrait jaxb2 être configuré pour revenir à un type de base ParentType quand il doit unmarshall un XML qui contient un élément d'un type inconnu, comme dans l'exemple suivant :

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

Normalement, dans cette situation, JAXB lance une exception qui dit que ChildType2 est un type non reconnu.

+0

+1 - JAXB peut def Initiez de manière intuitive 'xsi: type' dans une hiérarchie d'héritage (http://blog.bdoughan.com/2010/11/jaxb-and-inheritance-using-xsitype.html). Votre question est spécifiquement comment gérer le cas où 'xsi: type' ne correspond pas à une classe que JAXB est au courant? –

+0

Oui, Blaise, ma question concerne le cas où xsi: type correspond à une classe que JAXB ignore. –

Répondre

2

Ce n'est pas exactement ce dont vous avez besoin, mais vous pouvez utiliser @XmlAnyElement pour masquer les types inconnus en tant qu'éléments DOM.

Considérons une classe Customer avec le champ extras annoté avec un fourre-tout @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 Exemple:

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

Salary et Age sont des types inconnus, et sont stockés dans notre liste d'extras quand nous unmarshal:

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()); 

Sortie:

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

+1 - De même si vous définissez '@XmlAnyElement (lax = true)' alors votre implémentation JAXB convertira les types connus en objet: http://blog.bdoughan.com/2010/08/using-xmlanyelement-to-build -generic.html –

+0

Le problème avec '@ XmlAnyElement' est que vous devez parcourir la liste des éléments afin de trouver ce dont vous avez besoin. Par exemple, dans mon cas, je veux être capable d'utiliser JAXB même si quelqu'un a mis à jour le schéma XML avec un nouveau type dont je ne suis pas au courant, mais qui est une extension d'un type connu. En outre, '@ XmlAnyElement' nécessite l'ajout d'éléments adnotated à n'importe quel endroit où des éléments inconnus peuvent apparaître et je ne connais pas ces emplacements. Je pense qu'il pourrait y avoir une option de configuration ou des options qui pourraient permettre cela. –

Questions connexes