2011-05-11 52 views
3

這與我昨天問的this questionthis question稍有關係。如何基於JAXB中元素的存在來分配布爾值?

我想使用布爾值來確定XML文檔中是否存在元素。即我解析文件允許元素如以下:

<FamilyMember> 
    <Name>Jeff</Name> 
</FamilyMember> 
<FamilyMember> 
    <Name>Spot</Name> 
    <IsPet/> 
</FamilyMember> 

在這個例子中,所述元素指定的FamilyMember是寵物,但有與此相關聯的元素沒有附加數據。我希望能夠告訴JAXB根據解析文件中是否存在該元素來返回布爾值。如果該元素存在,則該值應爲true;否則,它應該是錯誤的。如果可能的話,我希望通過XSD模式來生成我的Java類。

回答

0

您的IsPet顯示爲布爾值嗎?在這種情況下,我猜如果它不存在於XML中,布爾值將爲空。我認爲this question表明這種情況。

+0

這是一種我的問題的觀點。我可以將IsPet解析爲布爾值,但如果它不存在,它將返回null。我不想將它檢查爲null,而是將其值設置爲true,如果不爲null,則返回false。 – troyal 2011-05-11 20:47:15

3

你應該能夠有類似以下內容的XmlAdapter做到這一點:

一旦你的答案(How do I specify the adapter(s) which JAXB uses for marshaling/unmarshaling data?),你將能夠應用適配器。


以下是它是如何做到的。請注意,以下示例使用EclipseLink JAXB (MOXy),但在使用JAXB參考實現時引發異常。

FamilyMember

package example; 

import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlElementRef; 
import javax.xml.bind.annotation.XmlRootElement; 
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 

@XmlRootElement(name="FamilyMember") 
public class FamilyMember { 

    private boolean pet; 
    private String name; 

    @XmlElementRef 
    @XmlJavaTypeAdapter(IsPetAdapter.class) 
    public boolean isPet() { 
     return pet; 
    } 

    public void setPet(boolean pet) { 
     this.pet = pet; 
    } 

    @XmlElement(name="Name") 
    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

} 

IsPetAdapter

package example; 

import javax.xml.bind.annotation.XmlRootElement; 
import javax.xml.bind.annotation.adapters.XmlAdapter; 
import forum204.IsPetAdapter.IsPet; 

public class IsPetAdapter extends XmlAdapter<IsPet, Boolean> { 

    @Override 
    public Boolean unmarshal(IsPet v) throws Exception { 
     return null != v; 
    } 

    @Override 
    public IsPet marshal(Boolean v) throws Exception { 
     if(v) { 
      return new IsPet(); 
     } 
     return null; 
    } 

    @XmlRootElement(name="IsPet") 
    public static class IsPet { 
    } 

} 

演示

package example; 

import java.io.File; 

import javax.xml.bind.JAXBContext; 
import javax.xml.bind.Marshaller; 
import javax.xml.bind.Unmarshaller; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(FamilyMember.class); 

     Unmarshaller unmarshaller= jc.createUnmarshaller(); 
     FamilyMember fm = (FamilyMember) unmarshaller.unmarshal(new File("input.xml")); 

     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     marshaller.marshal(fm, System.out); 
    } 

} 
+0

在這種情況下,我的模式會是什麼樣子? – troyal 2011-05-11 23:14:16

+0

這種方法似乎也很難擴展...如果我有多個元素,如(除了)?我是否必須爲每個適配器類編寫一個新的適配器類,即使基本上我希望它們都做同樣的事情(如果元素存在,則返回true,否則返回false)? – troyal 2011-05-12 19:30:23

+0

@Blue - 我領導EclipseLink JAXB(MOXy),並且我已經輸入了一個功能的增強請求,這個功能可以使這個用例更易於映射(https://bugs.eclipse.org/345969)。請隨時爲錯誤添加詳細信息。 – 2011-05-16 15:36:05