2009-11-26 75 views
2

我有一個XML架構:JAXB minOccurs = 0。元素是否存在?

<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站點中的article使用附加的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()的返回值?

+0

您是使用Java 6中的JAXB還是使用1.5的獨立庫? JAXB如何生成類的方式發生了變化。特別是對於數組。嘗試最新的一個。 – 2009-11-27 02:31:00

+0

我使用JAXME(在Fedora上的軟件包是ws-jaxme-0.5.1-3.4.fc11.noarch)和Java 6(java-1.6.0-openjdk-1.6.0.0-30.b16.fc11.i586) 。 – 2009-11-27 21:26:40

+0

這似乎是JAXB 2.0的JAXME實現的一個特別問題。切換到Sun的實現時,如果元素未包含在XML消息中,getter將返回空值。 – 2009-11-30 20:45:38

回答

4

我根本沒有看到這個問題。對於我xjc生成Person類與性質latlonDouble類型。

如果我解組沒有<lat><lon>元素的XML文件,然後將所得的物體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()); 
    } 
} 

我:

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

輸出:

Fred 
1.0 
null 
+2

我剛剛嘗試過您的示例,並按您的建議工作。這是個好消息!這不是JAXB的限制,而是我的項目的一個問題。謝謝! – 2009-11-27 21:35:32

0

獲得0.0返回vs null的最可能原因是使用Double基本類型或Double對象類型。如果值爲空,Double基元將默認爲0.0,因爲null對於基元類型不是有效值。 Double對象將允許您爲這些字段分配一個空值。在你的Person類中的高峯可能會揭示這一點。

+1

是的,我認爲你是對的雙重對雙。然而,問題似乎源於JAXME將xsd:double轉換爲java原語double,Sun Java JAXB將xsd:double轉換爲java Double。 JAXME創建的代碼無法檢查是否設置了XML中的值。檢查0.0是不可取的,因爲0.0是經度和緯度的有效值。我已經切換到使用JAXB,以便我可以檢查null以確定元素是否提供。 – 2010-06-03 14:10:00