6

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

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

编组后的结果是

<Item xsi:nil="true"/>

虽然我希望它是

<Item/>

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

非常感谢

4

2 回答 2

1

注意: 我是EclipseLink JAXB (MOXy)负责人,也是JAXB (JSR-222)专家组的成员。

以下示例需要使用 MOXy 作为 JAXB 提供程序。XmlAdapter这是因为当字段/属性为空时,JAXB RI 不会调用。有关将 MOXy 指定为您的 JAXB 提供程序的信息,请参阅:

字符串适配器

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>

了解更多信息

于 2012-01-24T20:29:56.140 回答
-1

我发现更改 xsd 更容易

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

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

您将指定新名称并将名称设置为所属的任何对象名称

于 2012-04-23T18:57:11.753 回答