java - plugin - jaxb tutorial
¿Por qué JAXB a veces se correlaciona con JAXBElement? (2)
Hay una respuesta de marcador de posición en la guía no oficial con un enlace a un artículo que (para mí) no parece tener relación alguna.
Utilizo XJC para generar mis clases JAXB y aunque la mayoría de ellas se asignan entre sí como se esperaba, algunos elementos se asignan a JAXBElement<Foo>
. Esto es más molesto para los gráficos con ciclos, donde a veces el nodo primario de un elemento Foo será JAXBElement<Foo>
, que no tiene una propiedad principal, rompiendo el ciclo.
Puedo pensar en varias soluciones, pero sería mucho mejor si alguien pudiera explicarme este comportamiento. ¿Por qué JAXB a veces JAXBElement<Foo>
elemento <Foo>
a JAXBElement<Foo>
lugar de Foo?
¿Para evitar mapear a JAXBElement? He hecho estas cosas que me funcionan.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jaxb:extensionBindingPrefixes="xjc"
jaxb:version="2.0">
<xs:annotation>
<xs:appinfo>
<jaxb:globalBindings generateValueClass="false">
<xjc:simple />
</jaxb:globalBindings>
</xs:appinfo>
</xs:annotation>
</xs:schema>
Guarde este archivo en el archivo xml y suminístrelo como archivos de enlace.
Link referencia
Genere clases JAXB usando eclipse. No se olvide de proporcionar los archivos de enlace creados con el xml anterior y marque "Permitir extensiones de proveedores" como se muestra a continuación:
Con los cambios, puedo deshacerme de JAXBElement en las clases generadas xjc para convertir xsd en clases generadas JAXB.
JAXBElement se usa para preservar el nombre del elemento / espacio de nombres en casos de uso donde no hay suficiente información en el modelo de objetos. La ocurrencia más común es con grupos de sustitución:
Con Grupo de Sustitución:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.org"
xmlns="http://www.example.org"
elementFormDefault="qualified">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element ref="anElement"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="anElement" type="xs:string"/>
<xs:element name="aSubstituteElement" type="xs:string" substitutionGroup="anElement"/>
</xs:schema>
Generará:
package org.example;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.*;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"anElement"
})
@XmlRootElement(name = "root")
public class Root {
@XmlElementRef(name = "anElement", namespace = "http://www.example.org", type = JAXBElement.class)
protected JAXBElement<String> anElement;
public JAXBElement<String> getAnElement() {
return anElement;
}
public void setAnElement(JAXBElement<String> value) {
this.anElement = ((JAXBElement<String> ) value);
}
}
Sin Grupo de Sustitución:
Si eliminas el grupo de sustitución:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.org"
xmlns="http://www.example.org"
elementFormDefault="qualified">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element ref="anElement"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="anElement" type="xs:string"/>
</xs:schema>
Se generará la siguiente clase:
package org.example;
import javax.xml.bind.annotation.*;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"anElement"
})
@XmlRootElement(name = "root")
public class Root {
@XmlElement(required = true)
protected String anElement;
public String getAnElement() {
return anElement;
}
public void setAnElement(String value) {
this.anElement = value;
}
}
También puede obtener un JAXBElement cuando unmarshal, compare los siguientes ejemplos: