JAXB minOccurs = 0. Elemento existe ou não?
Pergunta
Eu tenho um esquema XML:
<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>
E eu tenho uma mensagem de XML:
<Person>
<name>Fred</name>
</Person>
Eu uso JAXB para gerar automaticamente minhas aulas (ou seja Person.java, etc).
Assim, em tempo de execução Eu uso JAXB para desempacotar a mensagem XML acima e obter uma instância de objeto Pessoa. Quando eu faço um p.getLat()
ou p.getLon()
os valores de retorno são 0.0, embora o XML original não continha <lat>
ou <lon>
elementos.
O que torna esta pior é que 0.0, 0.0 é uma latitude válido e longitude. É raro para uma pessoa a ser localizada lá, mas isso não vem ao ponto!
Um artigo no site da IBM sugeriu usando um elemento XML adicional como metadados para explicitamente indicar se o elemento opcional existe ou não. i.
<xsd:element name="hasLat" type="xsd:boolean"/>
<xsd:element name="hasLon" type="xsd:boolean"/>
Portanto, a mensagem XML acima seria:
<Person>
<name>Fred</name>
<hasLat>false</hasLat>
<hasLon>false</hasLon>
</Person>
Esta parece ser uma gambiarra. Deve haver uma maneira adequada com JAXB para verificar se o elemento existia para que eu possa confiar o valor de retorno do meu getLat()
, getLon()
?
Solução
Eu não vejo esse problema em tudo. Para mim xjc
gera uma classe Person
com as propriedades lat
e lon
com o tipo Double
.
Se eu desempacotar um arquivo XML sem <lat>
ou <lon>
elementos, então o Person
resultando objetos tem valores null
para essas propriedades, como seria de esperar.
Eu não sei como você começa 0.0
em qualquer lugar.
Meu XML Schema:
<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>
Meu 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());
}
}
Meu foo.xml
:
<Person>
<name>Fred</name>
<lat>1.0</lat>
</Person>
Output:
Fred 1.0 null
Outras dicas
A razão mais provável para obter 0,0 retornou vs nulo é o uso do tipo primitivo Duplo ou Duplo tipo de objeto. The Double primitiva será o padrão para 0.0 se o valor for nulo, uma vez nulo não é um valor válido para tipos primitivos. O objeto duplo permite-lhe atribuir um valor nulo para estes campos. Um pico na sua classe Pessoa provavelmente irá revelar isso.