2012-01-24 56 views
6

我在標註爲對象有一個String屬性如下:JAXB - 沒有XSI空標籤:無

@XmlElement(name = "Item", required = true, nillable = true) 
private String item; 

編組後的結果是

<Item xsi:nil="true"/> 

,而我想它是

<Item/> 

因爲接受我的XML消息的第三方服務希望它像後一種情況。我正在使用jaxb2。有誰知道我怎麼可能做到這一點?

非常感謝

回答

1

注:我是EclipseLink JAXB (MOXy)鉛和JAXB (JSR-222)專家小組的成員。

以下示例需要使用MOXy作爲JAXB提供程序。這是因爲當字段/屬性爲空時,JAXB RI不會調用XmlAdapter。有關指定莫西爲您的JAXB提供者的信息,請參閱:

StringAdapter

XmlAdapter將字符串值轉換爲對象與@XmlValue註釋的屬性。

package forum8986842; 

import javax.xml.bind.annotation.*; 
import javax.xml.bind.annotation.adapters.XmlAdapter; 

public class StringAdapter extends XmlAdapter<StringAdapter.AdaptedString, String>{ 

    @Override 
    public String unmarshal(AdaptedString adaptedString) throws Exception { 
     if(null == adaptedString) { 
      return null; 
     } 
     String string = adaptedString.value; 
     if("".equals(string)) { 
      return null; 
     } 
     return string; 
    } 

    @Override 
    public AdaptedString marshal(String string) throws Exception { 
     AdaptedString adaptedString = new AdaptedString(); 
     adaptedString.value = string; 
     return adaptedString; 
    } 

    public static class AdaptedString { 
     @XmlValue public String value; 
    } 

} 

@XmlJavaTypeAdapter註釋用於指定XmlAdapter

package forum8986842; 

import javax.xml.bind.annotation.*; 
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 

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

    private String item; 

    @XmlElement(name = "Item", required = true, nillable = true) 
    @XmlJavaTypeAdapter(StringAdapter.class) 
    public String getItem() { 
     return item; 
    } 

    public void setItem(String item) { 
     this.item = item; 
    } 

} 

演示

下面的代碼可以用於證明上述映射。兩個文檔使用一個空的Item元素,另一個填充Item元素。

package forum8986842; 

import java.io.StringReader; 
import javax.xml.bind.*; 

public class Demo { 

    private JAXBContext jc; 

    public Demo() throws JAXBException { 
     jc = JAXBContext.newInstance(Root.class); 
    } 

    public static void main(String[] args) throws Exception { 
     Demo demo = new Demo(); 
     demo.demo("<Root><Item/></Root>"); 
     demo.demo("<Root><Item>Hello World</Item></Root>"); 
    } 

    private void demo(String xml) throws JAXBException { 
     System.out.println("\n\nINPUT: " + xml); 
     StringReader stringReader = new StringReader(xml); 
     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     Root root = (Root) unmarshaller.unmarshal(stringReader); 

     System.out.println("ITEM: " + root.getItem()); 

     System.out.print("OUTPUT: "); 
     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true); 
     marshaller.marshal(root, System.out); 
    } 

} 

輸出

以下是從運行演示代碼的輸出:

INPUT: <Root><Item/></Root> 
ITEM: null 
OUTPUT: <Root><Item/></Root> 

INPUT: <Root><Item>Hello World</Item></Root> 
ITEM: Hello World 
OUTPUT: <Root><Item>Hello World</Item></Root> 

更多信息

0

我發現改變了XSD比較容易

<xs:element name="name"> 
    <xs:complexType/> 
</xs:element> 

,並在你的代碼,當你自動生成你的java的src /班

你會指定新名稱並將名稱設置爲

之下的任何對象名稱