JAXB minOccurs = 0. Элемент существует или нет? - PullRequest
2 голосов
/ 27 ноября 2009

У меня есть схема 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>

И у меня есть сообщение XML:

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

Я использую JAXB для автоматической генерации своих классов (т.е. Person.java и т. Д.).

Итак, во время выполнения я использую JAXB, чтобы демонтировать вышеприведенное сообщение XML и получить экземпляр объекта Person. Когда я делаю p.getLat() или p.getLon(), возвращаемые значения равны 0.0, даже если исходный XML не содержал <lat> или <lon> элементов.

Что еще хуже, это то, что 0.0, 0.0 - это действительные широта и долгота. Человек редко бывает там, но это не относится к делу!

В статье на сайте IBM предлагается использовать дополнительный элемент XML в качестве метаданных, чтобы явно указать, существует ли необязательный элемент или нет. т.е.

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

Таким образом, приведенное выше XML-сообщение станет:

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

Это похоже на уродливый хак. У JAXB должен быть правильный способ проверить, существует ли элемент, чтобы я мог доверять возвращаемому значению из моих getLat(), getLon()?

Ответы [ 2 ]

4 голосов
/ 27 ноября 2009

Я вообще не вижу этой проблемы. Для меня xjc создает класс Person со свойствами lat и lon с типом Double.

Если я отменю маршалирование XML-файла без элементов <lat> или <lon>, то получающиеся объекты Person будут иметь значения null для этих свойств, как и следовало ожидать.

Я не знаю, откуда у вас 0.0.

Моя 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>

Мой 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());
  }
}

Мой foo.xml:

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

Выход:

Fred
1.0
null
0 голосов
/ 02 июня 2010

Наиболее вероятной причиной получения 0.0, возвращаемых против нуля, является использование типа двойного примитива или типа двойного объекта. Примитив Double по умолчанию будет равен 0.0, если значение равно нулю, поскольку значение null не является допустимым значением для типов примитивов. Объект Double позволит вам присвоить этим полям нулевое значение. Пик в вашем классе Person, вероятно, покажет это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...