2012-01-16 110 views
5

有沒有什麼辦法讓JAXB不保存字段,這些值是@Element註釋中指定的默認值,然後在從XML加載元素爲null或空的元素時爲其設置值?舉個例子:JAXB避免保存默認值

class Example 
{ 
    @XmlElement(defaultValue="default1") 
    String prop1; 
} 

Example example = new Example(); 
example.setProp1("default1"); 
jaxbMarshaller.marshal(example, aFile); 

應該產生:

<example/> 

和裝載

Example example = (Example) jaxbUnMarshaller.unmarshal(aFile); 
assertTrue(example.getProp1().equals("default1")); 

我想這樣做是爲了產生一個乾淨的XML配置文件時,並使其更好可讀性和更小的尺寸。

後悔和提前致謝。

+0

我不相信JAXB會檢查該值是否等於默認值,因此應該跳過。第二剪切應該工作。斷言失敗? – 2012-01-16 20:05:32

回答

3

你可以做這樣的事情通過利用XmlAccessorType(XmlAccessType.FIELD)並把邏輯的get/set方法如下:

package forum8885011; 

import javax.xml.bind.annotation.*; 

@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
class Example { 

    private static final String PROP1_DEFAULT = "default1"; 
    private static final String PROP2_DEFAULT = "123"; 

    @XmlElement(defaultValue=PROP1_DEFAULT) 
    String prop1; 

    @XmlElement(defaultValue=PROP2_DEFAULT) 
    Integer prop2; 

    public String getProp1() { 
     if(null == prop1) { 
      return PROP1_DEFAULT; 
     } 
     return prop1; 
    } 

    public void setProp1(String value) { 
     if(PROP1_DEFAULT.equals(value)) { 
      prop1 = null; 
     } else { 
      prop1 = value; 
     } 
    } 

    public int getProp2() { 
     if(null == prop2) { 
      return Integer.valueOf(PROP2_DEFAULT); 
     } 
     return prop2; 
    } 

    public void setProp2(int value) { 
     if(PROP2_DEFAULT.equals(String.valueOf(value))) { 
      prop2 = null; 
     } else { 
      prop2 = value; 
     } 
    } 

} 

演示

package forum8885011; 

import javax.xml.bind.*; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(Example.class); 
     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 

     Example example = new Example(); 
     example.setProp1("default1"); 
     example.setProp2(123); 
     System.out.println(example.getProp1()); 
     System.out.println(example.getProp2()); 
     marshaller.marshal(example, System.out); 

     example.setProp1("FOO"); 
     example.setProp2(456); 
     System.out.println(example.getProp1()); 
     System.out.println(example.getProp2()); 
     marshaller.marshal(example, System.out); 
    } 

} 

輸出

default1 
123 
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<example/> 
FOO 
456 
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<example> 
    <prop1>FOO</prop1> 
    <prop2>456</prop2> 
</example> 

更多信息

+0

嗯,正是我想避免「所有」代碼,並使JAXB自動加載並保存文檔。無論如何,我可以處理基本類型(即避免保存int的,因爲我不能讓它們爲空)?將它們聲明爲Integer? – okelet 2012-01-16 20:52:31

+0

@okelet - 我用'int'屬性更新了我的代碼。 – 2012-01-16 21:10:37

0

對於一個編程解決方案,這裏還有好老Apache commons XmlSchema,你可以覈對與XmlSchemaElement.getDefaultValue默認值()

因此,像

XmlSchemaElement elem = schema.getElementByName(ELEMENT_QNAME); 
String defval = elem.getDefaultValue(); 

你應該能夠做你所需要的。最後還沒有嘗試過,因爲我需要一個更直接的解決方案,但我希望這有所幫助。