Jim*_*ugh 3 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"/>
Run Code Online (Sandbox Code Playgroud)
我试图找到一种干净的方法来转换我收到的每个元素,xsi:nil="true"当它被解组为 JAXB 对象时被标记为null。所以像这样:
<myIntElementName xsi:nil="true" />
Run Code Online (Sandbox Code Playgroud)
应该导致我的 JAXB 对象具有一个myIntElementName值为 null的属性,而不是一个JAXBElement将 nil 属性设置为 true(或任何类似内容)的对象。我对向我发送使用该nillable属性的 XML 的系统没有任何控制权,因此我需要在收到它时对其进行转换。
@XmlElement(nillable=true)
您只需要@XmlElement(nillable=true)在您的字段/属性上指定即可获得此行为:
@XmlElement(nillable=true)
private String foo;
Run Code Online (Sandbox Code Playgroud)
从 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>
Run Code Online (Sandbox Code Playgroud)
为什么你会得到一个类型的属性 JAXBElement
JAXBElement在您的模型中生成了一个 type 属性,因为您有一个可空元素 this is minOccurs="0"。的使用JAXBElement允许模型区分丢失的元素(属性为空)和元素的存在nil="true"(JAXBElement with nil flag set)。
<xs:element name="myStringElementName" type="xs:string"
nillable="true" minOccurs="0" />
Run Code Online (Sandbox Code Playgroud)
外部绑定文件 (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>
Run Code Online (Sandbox Code Playgroud)
XJC呼叫
下面是如何利用来自 XJC 调用的外部绑定文件的示例
xjc -b binding.xml schema.xsd
Run Code Online (Sandbox Code Playgroud)
生成模型 (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;
}
}
Run Code Online (Sandbox Code Playgroud)
想要查询更多的信息