Convert nil=“true” to null during unmarshal operation

ⅰ亾dé卋堺 提交于 2020-01-13 19:08:08

问题


I am receiving XML from a server whose schema specifies nearly every element as:

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

I'm trying to find a clean way to convert every element that I receive that is marked as xsi:nil="true" to a null when it is unmarshalled into a JAXB object. So something like this:

<myIntElementName xsi:nil="true" />

Should result in my JAXB object having a myIntElementName property with a value of null, rather than a JAXBElement object with a nil property set to true (or anything along those lines). I don't have any control over the system that is sending me the XML that uses the nillable attribute, so I need to convert this on my end when I receive it.


回答1:


@XmlElement(nillable=true)

You just need to specify @XmlElement(nillable=true) on your field/property to get this behaviour:

@XmlElement(nillable=true)
private String foo;

Generating From an XML Schema

Below I'll demonstrate how to generate this mapping if you are staring from an XML schema.

XML Schema (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>

Why you get a property of type JAXBElement

A property of type JAXBElement is generated in your model because you have a nillable element this is minOccurs="0". The use of JAXBElement allows the model to differentiate between an missing element (property is null) and the presence of the element with nil="true" (JAXBElement with nil flag set).

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

External Binding File (binding.xml)

An external binding file can be specified to tell the JAXB implementation not to generate any properties of type JAXBElement. Note this will make it impossible for JAXB to round trip all XML documents.

<?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 Call

Below is an example of how to leverage an external binding file from the XJC Call

xjc -b binding.xml schema.xsd

Generated Model (Foo)

The generated model will look something like the following:

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

}

For More Information

  • http://blog.bdoughan.com/2012/04/binding-to-json-xml-handling-null.html


来源:https://stackoverflow.com/questions/12519636/convert-nil-true-to-null-during-unmarshal-operation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!