在解组操作期间将nil =“true”转换为null

时间:2012-09-20 19:31:10

标签: java xml jaxb jaxb2 xml-nil

我从一个服务器接收XML,该服务器的模式几乎将每个元素指定为:

<xs:element name="myStringElementName" type="xs:string" nillable="true" minOccurs="0"/>
<xs:element name="myIntElementName" type="xs:int" nillable="true" minOccurs="0"/>

我正在尝试找到一种干净的方法,将我收到的标记为xsi:nil="true"的每个元素转换为null,当它被解组到JAXB对象中时。所以像这样:

<myIntElementName xsi:nil="true" />

应该导致我的JAXB对象具有值为null的myIntElementName属性,而不是将nil属性设置为true的JAXBElement对象(或沿着这些行的任何内容)。我对发送给我使用nillable属性的XML的系统没有任何控制权,所以当我收到它时,我需要在我的结尾转换它。

1 个答案:

答案 0 :(得分:4)

<强> @XmlElement(的nillable =真)

您只需在字段/属性上指定@XmlElement(nillable=true)即可获得此行为:

@XmlElement(nillable=true)
private String foo;

从XML架构生成

下面我将演示如何从XML模式开始生成此映射。

XML架构(schema.xsd)

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="foo">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="myStringElementName" type="xs:string"
                    nillable="true" minOccurs="0" />
                <xs:element name="myIntElementName" type="xs:int"
                    nillable="true" minOccurs="0" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

为什么会获得JAXBElement 类型的

属性

在模型中生成类型JAXBElement的属性,因为您有一个可为空的元素minOccurs="0"JAXBElement的使用允许模型区分缺少的元素(属性为null)和带有nil="true"的元素的存在(设置了nil标志的JAXBElement)。

<xs:element name="myStringElementName" type="xs:string"
                        nillable="true" minOccurs="0" />

外部绑定文件(binding.xml)

可以指定外部绑定文件以告知JAXB实现不生成类型JAXBElement的任何属性。请注意,这将使JAXB无法遍历所有XML文档。

<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings version="2.0"
               xmlns:jaxb="http://java.sun.com/xml/ns/jaxb">
    <jaxb:bindings>
        <jaxb:globalBindings generateElementProperty="false"/>
    </jaxb:bindings>
</jaxb:bindings>

XJC致电

以下是如何利用XJC Call

中的外部绑定文件的示例
xjc -b binding.xml schema.xsd

生成的模型(Foo)

生成的模型如下所示:

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "myStringElementName",
    "myIntElementName"
})
@XmlRootElement(name = "foo")
public class Foo {

    @XmlElement(nillable = true)
    protected String myStringElementName;
    @XmlElement(nillable = true)
    protected Integer myIntElementName;

    public String getMyStringElementName() {
        return myStringElementName;
    }

    public void setMyStringElementName(String value) {
        this.myStringElementName = value;
    }

    public Integer getMyIntElementName() {
        return myIntElementName;
    }

    public void setMyIntElementName(Integer value) {
        this.myIntElementName = value;
    }

}

了解更多信息