2009-04-26 9 views
2

J'ai un XSD qui ressemble à ceci (extrait):JAXB Types problème

<xs:complexType name="IDType"> 
    <xs:choice minOccurs="1" maxOccurs="2"> 
    <xs:element name="FileID" minOccurs="0" maxOccurs="1" type="an..35" /> 
    <xs:element name="IDNumber1" minOccurs="0" maxOccurs="1" type="an..35" /> 
    <xs:element name="Number" minOccurs="0" maxOccurs="1" type="an..35" /> 
    <xs:element name="PNumber" minOccurs="0" maxOccurs="1" type="an..35" /> 
    <xs:element name="SS"  minOccurs="0" maxOccurs="1" type="an..35" /> 
    <xs:element name="Player" minOccurs="0" maxOccurs="1" type="an..35" /> 
    <xs:element name="Prior"  minOccurs="0" maxOccurs="1" type="an..35" /> 
    <xs:element name="BIN"  minOccurs="0" maxOccurs="1" type="an..35" /> 
    <xs:element name="Mutual" minOccurs="0" maxOccurs="1" type="an..35" /> 
    </xs:choice> 
</xs:complexType> 
<xs:simpleType name="an..35"> 
    <xs:restriction base="an"> 
    <xs:maxLength value="35" /> 
    </xs:restriction> 
</xs:simpleType> 

<xs:simpleType name="an"> 
    <xs:restriction base="xs:string"> 
    <xs:pattern value="[ !-~]*" /> 
    </xs:restriction> 
</xs:simpleType> 

Pour une raison pour cela est le code Java qui obtient généré:

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "IDType", propOrder = { 
    "fileID" 
}) 
public class PatientIDType { 
    @XmlElementRefs({ 
     @XmlElementRef(name = "FileED", namespace = "http://www.surescripts.com/messaging", type = JAXBElement.class), 
     @XmlElementRef(name = "IDNumber1", namespace = "http://www.surescripts.com/messaging", type = JAXBElement.class), 
     @XmlElementRef(name = "Number", namespace = "http://www.surescripts.com/messaging", type = JAXBElement.class), 
     @XmlElementRef(name = "PNumber", namespace = "http://www.surescripts.com/messaging", type = JAXBElement.class), 
     @XmlElementRef(name = "SS", namespace = "http://www.surescripts.com/messaging", type = JAXBElement.class), 
     @XmlElementRef(name = "Plaer", namespace = "http://www.surescripts.com/messaging", type = JAXBElement.class), 
     @XmlElementRef(name = "Prior", namespace = "http://www.surescripts.com/messaging", type = JAXBElement.class), 
     @XmlElementRef(name = "BIN", namespace = "http://www.surescripts.com/messaging", type = JAXBElement.class), 
     @XmlElementRef(name = "Mutual", namespace = "http://www.surescripts.com/messaging", type = JAXBElement.class) 
    }) 
    protected List<JAXBElement<String>> fileID; 
    /** 
    * Gets the value of the fileID property. 
    * 
    * <p> 
    * This accessor method returns a reference to the live list, 
    * not a snapshot. Therefore any modification you make to the 
    * returned list will be present inside the JAXB object. 
    * This is why there is not a <CODE>set</CODE> method for the fileID property. 
    * 
    * <p> 
    * For example, to add a new item, do as follows: 
    * <pre> 
    * getFileID().add(newItem); 
    * </pre> 
    * 
    * 
    * <p> 
    * Objects of the following type(s) are allowed in the list 
    * {@link JAXBElement }{@code <}{@link String }{@code >} 
    * {@link JAXBElement }{@code <}{@link String }{@code >} 
    * {@link JAXBElement }{@code <}{@link String }{@code >} 
    * {@link JAXBElement }{@code <}{@link String }{@code >} 
    * {@link JAXBElement }{@code <}{@link String }{@code >} 
    * {@link JAXBElement }{@code <}{@link String }{@code >} 
    * {@link JAXBElement }{@code <}{@link String }{@code >} 
    * {@link JAXBElement }{@code <}{@link String }{@code >} 
    * {@link JAXBElement }{@code <}{@link String }{@code >} 
    */ 
    public List<JAXBElement<String>> getFileID() { 
     if (fileID == null) { 
      fileID = new ArrayList<JAXBElement<String>>(); 
     } 
     return this.fileID; 
    } 

Pourquoi la classe générée comme ceci et tout simplement pas une sorte de tableau de chaînes? Je ne veux vraiment pas avoir à créer des JAXBElements chaque fois que je veux créer quelque chose?

Comment puis-je le générer des classes pour chacun des types qui représentent simplement une chaîne ou quelque chose comme ça?

Merci à l'avance,

Ian

+0

Notez que votre extrait de schéma semble être manquant (ou n'est pas cité pour être affiché correctement?). – StaxMan

Répondre

6

Ce code est généré parce que votre type complexe, idtype, contient un choix avec un MaxOccurrence supérieur à un, ici:

< xs: choix minOccurs = "1" maxOccurs = "2" >

Le contenu de cette liste sont des éléments avec différents noms mais le même tapez. Cela n'a pas d'équivalent dans les modèles orientés objet standards. JAXB utilise ensuite la classe JAXBElement pour contourner ce problème: un JAXBElement enveloppe un objet simple contenant les données et lui attribue un QName.

Ainsi, vous pouvez lire cette liste et écrire à la liste sans ambiguïté en fournissant:

  • L'objet de données (dans votre cas une chaîne puisque toutes les restrictions de chaîne sont caractérisés comme Java String)
  • Un JAXBElement dont getValue() méthode renvoie la chaîne

la spécification JAXB contient assez détaillées et des explications relativement complexes de la façon de traiter la répétition des choix et des séquences répétées. Notez que si votre séquence contenait des objets de types différents ainsi que des noms différents, vous finiriez par Liste <Objet>.

Ce fut la longue explication, maintenant voici quelques options:

  • Si vous pouvez modifier le schéma, mettre un élément d'emballage autour des 8 articles, par exemple, « wrapper ».Wrapper contiendra un seul choix des éléments; Ensuite, make IDType contient une séquence d'éléments Wrapper avec minOccurs = 1 et maxOccurs = 2.
  • Créez vous-même quelques fonctions d'aide pour créer rapidement les JAXBElements. JAXB met une classe d'usine dans votre package cible qui peut vous aider - par exemple, il contient des références à l'espace de noms de schéma, etc.
+0

Réponse parfaite. Je vous remercie. Malheureusement, il s'agit d'un XSD fourni de l'extérieur, donc je vais devoir utiliser la deuxième option. Pas mon préféré mais ça marchera certainement –

1

Si vous utilisez la mise en œuvre Sun JAXB, vous pouvez essayer de compiler avec le xjc: mode simple activé. Voir la documentation sur simplified binding pour un exemple. Il devrait tourner

public class PatientIDType { 
    protected List<JAXBElement<String>> fileID; 
} 

pour

public class PatientIDType { 
    String fileID; 
    ... 
} 

Vous aurez besoin de compiler votre schéma avec un fichier de personnalisation obligatoire. Voir Kohsuke's blog pour un exemple de la façon de le faire.

+0

J'ai essayé d'ajouter cette liaison mais la sortie reste la même. Est-ce que je manque quelque chose? [code] [/ code] –

+0

étrange qu'il ne l'a pas n'importe quoi. A-t-il changé l'une des autres classes Java? La chose la plus remarquable est la pluralisation des noms de collections. Utilisez-vous directement XJC comme xjc -extension simpleBinding.schemalet abc.xsd ? – deverton

+0

Il y a eu quelques changements mais rien de significatif. Je l'appelle en utilisant ant avec l'attribut extension = "true" –

3

Votre classe ObejctFActory devrait avoir la createMethod pour thosr valeurs, somthing comme

@XmlElementDecl(namespace = "http://www.surescripts.com/messaging", name = "SocialSecurity", scope = PatientIDType.class) 
public JAXBElement<String> createPatientIDTypeSocialSecurity(String value) { 
    return new JAXBElement<String>(_PayerIDTypeSocialSecurity_QNAME, String.class, PatientIDType.class, value); 
} 
Questions connexes