TL;博士
为了
@XmlElementRef(name="foo", required=false)
protected JAXBElement<String> foo;
文档中不存在的节点将对应于该字段为空。文档中存在的 XML 元素xsi:nil="true"
将对应于作为 的实例的JAXBElement
值,其值为null
。
您还可以提供一个 XML 模式,而不是让 JAXB 使用location
包级别@XmlSchema
注释上的属性生成一个。
@XmlSchema(
...
location="http://www.example.com/schema/root.xsd")
package forum19665550;
import javax.xml.bind.annotation.XmlSchema;
元帅/元帅
Java 模型
根
这是一个具有两个字段的对象,可以表示可选数据和可空数据。
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {
@XmlElementRef(name="foo", required=false)
protected JAXBElement<String> foo;
@XmlElementRef(name="bar", required=false)
protected JAXBElement<String> bar;
}
对象工厂
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.*;
import javax.xml.namespace.QName;
@XmlRegistry
public class ObjectFactory {
@XmlElementDecl(name="foo")
public JAXBElement<String> createFoo(String foo) {
return new JAXBElement<String>(new QName("foo"), String.class, foo);
}
@XmlElementDecl(name="bar")
public JAXBElement<String> createBar(String bar) {
return new JAXBElement<String>(new QName("bar"), String.class, bar);
}
}
演示代码
演示
下面的演示代码将研究 和 值的foo
差异bar
。您可以使用JAXBIntrospector
该类来获取JAXBElement
. EclipseLink JAXB (MOXy) 中有一个与解组JAXBElement
包装空值的实例相关的错误(请参阅: http ://bugs.eclipse.org/420746 )。
import java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Root.class, ObjectFactory.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum19665550/input.xml");
Root root = (Root) unmarshaller.unmarshal(xml);
System.out.println("foo was set: " + (root.foo != null));
System.out.println("bar was set: " + (root.bar != null));
System.out.println("foo value: " + root.foo);
System.out.println("bar value: " + root.bar);
System.out.println("foo unwrapped value: " + JAXBIntrospector.getValue(root.foo));
System.out.println("bar unwrapped value: " + JAXBIntrospector.getValue(root.bar));
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(root, System.out);
}
}
输入.xml/输出
在结果输出中,我们看到我们可以区分文档中不存在的元素和具有 `xsi:nil="true" 的元素,并且结果值仍然为 null。
foo was set: false
bar was set: true
foo value: null
bar value: javax.xml.bind.JAXBElement@4af42ea0
foo unwrapped value: null
bar unwrapped value: null
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
<bar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
生成 XML 模式
演示代码
生成模式
下面是一些 JAXB 代码,它们将从带注释的模型生成 XML 模式。
import java.io.IOException;
import javax.xml.bind.*;
import javax.xml.transform.Result;
import javax.xml.transform.stream.StreamResult;
public class GenerateSchema {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Root.class);
jc.generateSchema(new SchemaOutputResolver() {
@Override
public Result createOutput(String namespaceUri,
String suggestedFileName) throws IOException {
StreamResult result = new StreamResult(System.out);
result.setSystemId(suggestedFileName);
return result;
}
});
}
}
输出
这是生成的 XML 模式。你是对的,它并不表示foo
andbar
元素是可空的。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="bar" type="xs:string"/>
<xs:element name="foo" type="xs:string"/>
<xs:element name="root" type="root"/>
<xs:complexType name="root">
<xs:sequence>
<xs:element ref="foo" minOccurs="0"/>
<xs:element ref="bar" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
提供 XML 模式
您可以指向现有的包含更多信息的模型,而不是让 JAXB 从您的模型派生 XML Schema。
包信息
这是通过location
在包级别@XmlSchema
注释上指定属性来完成的。
@XmlSchema(
...
location="http://www.example.com/schema/root.xsd")
package forum19665550;
import javax.xml.bind.annotation.XmlSchema;