2009-11-26 3 views
2

je un schéma XML:JAXB minOccurs = 0. L'élément existe ou pas?

<xsd:element name="Person"> 
<xsd:complexType> 
    <xsd:sequence> 
    <xsd:element name="name" type="xsd:string" /> 
    <xsd:element name="lat" type="xsd:double" minOccurs="0"/> 
    <xsd:element name="lon" type="xsd:double" minOccurs="0"/> 
    </xsd:sequence> 
</xsd:complexType> 
</xsd:element> 

Et j'ai un message XML:

<Person> 
<name>Fred</name> 
</Person> 

J'utilise JAXB pour générer automatiquement mes cours (à savoir Person.java, etc.). Donc, au moment de l'exécution, j'utilise JAXB pour démâler le message XML ci-dessus et obtenir une instance d'objet Person. Quand je fais un p.getLat() ou p.getLon() les valeurs de retour sont 0.0 même si le XML original n'a pas contenu <lat> ou <lon> éléments. Ce qui rend cette situation pire est que 0,0, 0,0 est une latitude et une longitude valides. Il est rare qu'une personne soit localisée là mais c'est hors de propos! Un article sur le site IBM a suggéré d'utiliser un élément XML supplémentaire en tant que métadonnées pour indiquer explicitement si l'élément facultatif existe ou non. à savoir

<xsd:element name="hasLat" type="xsd:boolean"/> 
<xsd:element name="hasLon" type="xsd:boolean"/> 

Le message XML ci-dessus deviendrait:

<Person> 
<name>Fred</name> 
<hasLat>false</hasLat> 
<hasLon>false</hasLon> 
</Person> 

Cela semble être une bidouille horrible. Il doit y avoir un moyen approprié avec JAXB pour vérifier si l'élément existait afin que je puisse faire confiance à la valeur de retour de mon getLat(), getLon()?

+0

Utilisez-vous JAXB à partir de Java 6 ou de la bibliothèque séparée travaillant avec 1.5? Il y a eu des changements dans la façon dont JAXB génère des classes en cours de route. en particulier pour les tableaux. Essayez le dernier. –

+0

J'utilise JAXME (sur Fedora le paquet est ws-jaxme-0.5.1-3.4.fc11.noarch) et Java 6 (java-1.6.0-openjdk-1.6.0.0-30.b16.fc11.i586) . –

+0

Cela semble être un problème spécifique à l'implémentation JAXME de JAXB 2.0. Passant à l'implémentation de Sun, le getter renvoie une valeur nulle si l'élément n'a pas été inclus dans le message XML. –

Répondre

4

Je ne vois pas ce problème du tout. Pour moi, xjc génère une classe Person avec les propriétés lat et lon avec le type Double.

Si j'unmarshall un fichier XML sans <lat> ou <lon> éléments, puis les objets Person résultant a null valeurs pour ces propriétés, comme je pense.

Je ne sais pas comment vous obtenez 0.0 n'importe où.

Mon schéma XML:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
     targetNamespace="http://www.example.com/person"> 
<xsd:element name="Person"> 
    <xsd:complexType> 
    <xsd:sequence> 
    <xsd:element name="name" type="xsd:string" /> 
    <xsd:element name="lat" type="xsd:double" minOccurs="0"/> 
    <xsd:element name="lon" type="xsd:double" minOccurs="0"/> 
    </xsd:sequence> 
    </xsd:complexType> 
</xsd:element> 
</xsd:schema> 

Mon Test.java:

import com.example.person.Person; 
import javax.xml.bind.JAXB; 
import java.io.File; 

public class Test { 
    public static void main(String[] args) { 
    Person p = JAXB.unmarshal(new File("foo.xml"), Person.class); 
    System.out.println(p.getName()); 
    System.out.println(p.getLat()); 
    System.out.println(p.getLon()); 
    } 
} 

Mon :

<Person> 
<name>Fred</name> 
<lat>1.0</lat> 
</Person> 

Sortie:

Fred 
1.0 
null 
+2

J'ai juste essayé votre exemple et cela fonctionne comme vous l'avez suggéré. C'est une bonne nouvelle! Ce n'est pas une limitation de JAXB mais un problème avec mon projet. Je vous remercie! –

0

La raison la plus probable pour obtenir 0.0 renvoyé vs null est l'utilisation du type Double primitive ou Double. La primitive Double sera par défaut à 0.0 si la valeur est nulle, car null n'est pas une valeur valide pour les types primitifs. L'objet Double vous permettra d'attribuer une valeur nulle à ces champs. Un pic sur votre classe Person va probablement le révéler.

+1

Oui, je pense que vous avez raison sur le double contre le double. Cependant le problème semble provenir de JAXME convertissant xsd: double en java primitive double et Sun Java JAXB en convertissant un xsd: double en un java Double. Le code JAXME gererated ne permet pas de vérifier si les valeurs dans le fichier XML ont été définies. La vérification de 0.0 n'est pas souhaitable car 0.0 est une valeur valide pour la latitude et la longitude. Je suis passé à utiliser JAXB afin que je puisse vérifier null pour déterminer si l'élément a été fourni. –

Questions connexes