JAXB - 没有xsi:nil的空标签

时间:2012-01-24 12:31:19

标签: java xml jaxb jaxb2 xsi

我在一个对象中有一个String属性,注释如下:

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

封送后的结果是

<Item xsi:nil="true"/>

虽然我希望它是

<Item/>

因为接受我的XML消息的第三方服务希望它像后一种情况一样。我正在使用jaxb2。有谁知道我怎么可能这样做?

非常感谢

2 个答案:

答案 0 :(得分:1)

注意:我是EclipseLink JAXB (MOXy)主管,是JAXB (JSR-222)专家组的成员。

以下示例要求使用MOXy作为JAXB提供程序。这是因为当field / property为null时,JAXB RI不会调用XmlAdapter。有关将MOXy指定为JAXB提供程序的信息,请参阅:

<强> StringAdapter

XmlAdapter会将String值转换为具有注释为@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>

了解更多信息

答案 1 :(得分:-1)

我发现更改xsd更容易

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

并在您的代码中,当您自动生成java src / classes

您将指定新名称并将名称设置为

下属于哪个对象名称