[英]JAXB converts @XmlElementRefs and @XmlElements to xs:choice
I have 4 classes. 我有4节课。
Person
class, and abstract ContactInformation
with Phone
and Address
class extending it. Person
类,以及使用Phone
和Address
类扩展它的抽象ContactInformation
。
@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<>();
}
ContactInformation
is used only as container: ContactInformation
仅用作容器:
public abstract class ContactInfomation { /* empty class */ }
Phone
class: Phone
类:
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
public class Phone extends ContactInfomation {
@XmlElement(required = true, nillable = false)
private String number;
}
And Address
class: 和
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 @XmlElementrefs
to @XmlElements
in Person
class, nothing happens. 问题是,当我改变
@XmlElementrefs
到@XmlElements
在Person
类,没有任何反应。 JAXB
maps them to xs:choice
. JAXB
将它们映射到xs:choice
。 The XML output is same as before and schemagen
generates the same schema as before. XML输出与以前相同,
schemagen
生成与以前相同的模式。 Here is a sample output: 这是一个示例输出:
<?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 @XmlElementRef
uses it for Substitution group and XML choice. @XmlElementRef
文档将其用于替换组和XML选择。 I'm completely confused what is the difference of @XmlElementRefs
/ @XmlElementRef
and @XmlElements
/ @XmlElement
. 我完全混淆了
@XmlElementRefs
/ @XmlElementRef
和@XmlElements
/ @XmlElement
的区别。 Can anyone help? 有人可以帮忙吗?
Basic Differenece Between @XmlElement
and @XmlElementRef
@XmlElement
和@XmlElementRef
之间的基本区别
The difference between @XmlElement
and @XmlElementRef
is 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. XML Schema中的选择实际上是替换组可以完成的超集。 So to simplifiy the mapping JAXB leverages one mapping for both.
因此,为了简化映射,JAXB利用两个映射。
JAXB and Schema Generation JAXB和Schema Generation
JAXB can generated a Java model from any XML Schema, on the flip side JAXB does not preserve all metadata about the XML schema. JAXB可以从任何XML Schema生成Java模型,另一方面JAXB不保留有关XML模式的所有元数据。 Therefore JAXB can't generate every XML schema.
因此,JAXB无法生成每个XML架构。
@XmlElementRefs
/ @XmlElementRef
and @XmlRootElement
@XmlElementRefs
/ @XmlElementRef
和@XmlRootElement
Below is what you have in your model. 以下是您的模型中的内容。
Person 人
I have modified the mapping on the contacts
field to make the mapping to the Address
class 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 @XmlElementRef
the information you specify needs to correspond to a global element definition supplied by @XmlRootElement
or @XmlElementDecl
(see: http://blog.bdoughan.com/2012/07/jaxb-and-root-elements.html ). 使用
@XmlElementRef
进行映射时,您指定的信息需要与@XmlRootElement
或@XmlElementDecl
提供的全局元素定义相对应(请参阅: http : @XmlRootElement
。 HTML )。 By default the root element for the Person
class with be person
. 默认情况下,
Person
类的根元素为person
。
@XmlRootElement
public class Person {
Address 地址
I have used the @XmlRootElement
annotation 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
element
definitions within the choice
structure leverage ref
to 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 contacts
field 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 @XmlElementDecl
annotation. 所有引用的类都不需要使用
@XmlRootElement
注释(或者具有相应的@XmlElementDecl
注释。
public class Phone extends ContactInfomation {
Address 地址
If he class does have an @XmlRootElement
annotation it is not required to match the @XmlElement
annotation 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
element
definitions within the choice
structure are now defined as local elements. 我们看到
choice
结构中的element
定义现在被定义为局部元素。
<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>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.