3

我从服务器接收 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"在解组为 JAXB 对象时标记为 null 的元素。所以是这样的:

<myIntElementName xsi:nil="true" />

应该导致我的 JAXB 对象具有myIntElementName值为 null 的属性,而不是JAXBElement具有 nil 属性设置为 true 的对象(或任何类似的东西)。我无法控制向我发送使用该nillable属性的 XML 的系统,因此我需要在收到它时自行转换它。

4

1 回答 1

6

@XmlElement(nillable=true)

您只需要@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因为您有一个可空元素 this is minOccurs="0"。的使用JAXBElement允许模型区分缺少的元素(属性为空)和元素的存在nil="true"(JAXBElement with nil flag set)。

<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 调用中的外部绑定文件的示例

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;
    }

}

了解更多信息

于 2012-09-20T19:43:42.150 回答