Java JAXB 将 @XmlElementRefs 和 @XmlElements 转换为 xs:choice
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20873523/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JAXB converts @XmlElementRefs and @XmlElements to xs:choice
提问by Majid Azimi
I have 4 classes. Personclass, and abstract ContactInformationwith Phoneand Addressclass extending it.
我有4节课。Person类和抽象ContactInformation与Phone和Address类扩展它。
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
public class Person {
@XmlElement(required = true, nillable = false)
private String first;
@XmlElement(required = true, nillable = false)
private String last;
@XmlElementWrapper(name = "contacts")
@XmlElementRefs({
@XmlElementRef(name = "phone", type = Phone.class, required = true),
@XmlElementRef(name = "address", type = Address.class, required = true)
})
private final List<ContactInfomation> contacts = new ArrayList<>();
}
ContactInformationis used only as container:
ContactInformation仅用作容器:
public abstract class ContactInfomation { /* empty class */ }
Phoneclass:
Phone班级:
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
public class Phone extends ContactInfomation {
@XmlElement(required = true, nillable = false)
private String number;
}
And Addressclass:
和Address班级:
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
public class Address extends ContactInfomation {
@XmlElement(required = true, nillable = false)
private String country;
@XmlElement(required = true, nillable = false)
private String city;
}
The problem is when I change @XmlElementrefsto @XmlElementsin Personclass, nothing happens. JAXBmaps them to xs:choice. The XML output is same as before and schemagengenerates the same schema as before.
Here is a sample output:
问题是,当我换@XmlElementrefs到@XmlElements的Person类,没有任何反应。JAXB将它们映射到xs:choice. XML 输出与以前相同,并schemagen生成与以前相同的架构。这是一个示例输出:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<person>
<first>majid</first>
<last>azimi</last>
<contacts>
<address>
<country>US</country>
<city>Los Angles</city>
</address>
<address>
<country>US</country>
<city>New York</city>
</address>
<phone>
<number>5551037</number>
</phone>
</contacts>
</person>
And here is the schema:
这是架构:
<?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="address" type="address"/>
<xs:element name="person" type="person"/>
<xs:element name="phone" type="phone"/>
<xs:complexType name="person">
<xs:sequence>
<xs:element name="first" type="xs:string"/>
<xs:element name="last" type="xs:string"/>
<xs:element name="contacts" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="phone"/>
<xs:element ref="address"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="phone">
<xs:complexContent>
<xs:extension base="contactInfomation">
<xs:sequence>
<xs:element name="number" type="xs:string"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="contactInfomation" abstract="true">
<xs:sequence/>
</xs:complexType>
<xs:complexType name="address">
<xs:complexContent>
<xs:extension base="contactInfomation">
<xs:sequence>
<xs:element name="country" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
Documentation of @XmlElementRefuses it for Substitution group and XML choice. I'm completely confused what is the difference of @XmlElementRefs/@XmlElementRefand @XmlElements/@XmlElement. Can anyone help?
的文档@XmlElementRef使用它来替换组和XML的选择。我完全困惑@XmlElementRefs/@XmlElementRef和@XmlElements/的区别是什么@XmlElement。任何人都可以帮忙吗?
采纳答案by bdoughan
TL;DR
TL; 博士
Basic Differenece Between @XmlElementand @XmlElementRef
@XmlElement和之间的基本区别@XmlElementRef
The difference between @XmlElementand @XmlElementRefis if the corresponding generated element will contain a local element definition or a reference to a global element definition.
@XmlElement和之间的区别在于@XmlElementRef相应的生成元素是否将包含局部元素定义或对全局元素定义的引用。
Choice and Substitution Groups
选择和替代组
Choice in XML Schema is really a superset of what can be done with substitution groups. So to simplifiy the mapping JAXB leverages one mapping for both.
XML Schema 中的选择实际上是可以使用替换组完成的操作的超集。因此,为了简化映射,JAXB 为两者利用了一种映射。
JAXB and Schema Generation
JAXB 和模式生成
JAXB can generated a Java model from any XML Schema, on the flip side JAXB does not preserve all metadata about the XML schema. Therefore JAXB can't generate every XML schema.
JAXB 可以从任何 XML 模式生成 Java 模型,另一方面,JAXB 不保留有关 XML 模式的所有元数据。因此 JAXB 不能生成每个 XML 模式。
@XmlElementRefs/@XmlElementRefand @XmlRootElement
@XmlElementRefs/@XmlElementRef和@XmlRootElement
Below is what you have in your model.
以下是您的模型中的内容。
Person
人
I have modified the mapping on the contactsfield to make the mapping to the Addressclass more distinct.
我修改了contacts字段上的映射,使到Address类的映射更加清晰。
@XmlElementWrapper(name = "contacts")
@XmlElementRefs({
@XmlElementRef(name = "phone", type = Phone.class, required = true),
@XmlElementRef(name = "ADDRESS", type = Address.class, required = true)
})
private final List<ContactInfomation> contacts = new ArrayList<>();
Phone
电话
When you map with @XmlElementRefthe information you specify needs to correspond to a global element definition supplied by @XmlRootElementor @XmlElementDecl(see: http://blog.bdoughan.com/2012/07/jaxb-and-root-elements.html). By default the root element for the Personclass with be person.
当您使用@XmlElementRef您指定的信息进行映射时,需要对应于由@XmlRootElementor提供的全局元素定义@XmlElementDecl(请参阅:http: //blog.bdoughan.com/2012/07/jaxb-and-root-elements.html)。默认情况下,Person类的根元素为person。
@XmlRootElement
public class Person {
Address
地址
I have used the @XmlRootElementannotation to override the default name for the Address class.
我已经使用@XmlRootElement注释来覆盖Address class.
@XmlRootElement(name="ADDRESS")
public class Address extends ContactInfomation {
Generated XML Schema
生成的 XML 模式
Here is the generated schema. We see that the elementdefinitions within the choicestructure leverage refto reference an existing element instead of defining a local element.
这是生成的架构。我们看到结构中的element定义choice利用ref引用现有元素而不是定义本地元素。
<xs:element name="contacts" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="phone"/>
<xs:element ref="ADDRESS"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
@XmlElements/@XmlElement
@XmlElements/@XmlElement
I have changed the mapping on your contactsfield to use @XmlElements.
我已将您contacts字段上的映射更改为使用@XmlElements.
Person
人
@XmlElementWrapper(name = "contacts")
@XmlElements({
@XmlElement(name = "phone-number", type = Phone.class, required = true),
@XmlElement(name = "home-address", type = Address.class, required = true)
})
private final List<ContactInfomation> contacts = new ArrayList<>();
Phone
电话
None of the referenced classes are required to be annotated with @XmlRootElement(or have a corresponding @XmlElementDeclannotation.
引用的类都不需要注释@XmlRootElement(或具有相应的@XmlElementDecl注释。
public class Phone extends ContactInfomation {
Address
地址
If he class does have an @XmlRootElementannotation it is not required to match the @XmlElementannotation within the @XmlElements.
如果他类确实有@XmlRootElement它不需要匹配注释@XmlElement中的注释@XmlElements。
@XmlRootElement(name="ADDRESS")
public class Address extends ContactInfomation {
Generated XML Schema
生成的 XML 模式
Here is the generated schema. We see that the elementdefinitions within the choicestructure are now defined as local elements.
这是生成的架构。我们看到,element在中定义choice的结构现在被定义为本地元素。
<xs:element name="contacts" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:choice maxOccurs="unbounded">
<xs:element name="phone-number" type="phone"/>
<xs:element name="home-address" type="address"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>

