java - comando - ¿Cómo lidiar con JAXB ComplexType con datos MixedContent?
xsd to java jaxb (2)
Como mencionó, debe agregar el atributo mixed
para indicar que su tipo admite contenido mixto. Sin esto, su contenido XML no es válido:
<xsd:complexType name="TaxDescriptionType" mixed="true">
<xsd:sequence>
<xsd:element name="ShortName" type="xsd:string" />
</xsd:sequence>
<xsd:attribute ref="xml:lang" />
</xsd:complexType>
La clase TaxDescriptionType
generada tendrá la siguiente propiedad. Esencialmente, esto significa que todo el contenido no atribuible se almacenará en una List
. Esto es necesario porque necesita un mecanismo que indique dónde están los nodos de texto en el contenido del elemento.
@XmlElementRef(name = "ShortName", namespace = "http://www.example.org/schema", type = JAXBElement.class)
@XmlMixed
protected List<Serializable> content;
Va a llenar esta lista con instancias de String
(que representa nodos de texto) y JAXBElement
(que representa el contenido del elemento).
ALTERNATIVAMENTE
El contenido mixto generalmente hace la vida más complicada de lo necesario. Si es posible, recomendaría una representación XML alternativa.
<Tax>
<Money currency="USD">0.00</Money>
<Description xml:lang="en" ShortName="vatspecial">
17.5% Non-Recoverable
</Description>
</Tax>
O
<Tax>
<Money currency="USD">0.00</Money>
<Description xml:lang="en">
<LongName>17.5% Non-Recoverable</LongName>
<ShortName>vatspecial</ShortName>
</Description>
</Tax>
Tengo esta estructura XML:
<Tax>
<Money currency="USD">0.00</Money>
<Description xml:lang="en">
17.5% Non-Recoverable
<ShortName>vatspecial</ShortName>
</Description>
</Tax>
Tenga en cuenta que el nodo Description
tiene MixedContent
(compuesto por texto y XML) y esta es la parte XSD
respecto al nodo Description
:
<xsd:complexType name="TaxDescriptionType">
<xsd:sequence>
<xsd:element name="ShortName" type="xsd:string" />
</xsd:sequence>
<xsd:attribute ref="xml:lang" />
</xsd:complexType>
Todo está bien en este punto, XJC
genera las clases generadas como esta en TaxDescriptionType
:
package org.com.project;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.CollapsedStringAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
/**
* <p>Java class for TaxDescriptionType complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType name="TaxDescriptionType">
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="ShortName" type="{http://www.w3.org/2001/XMLSchema}string"/>
* </sequence>
* <attribute ref="{http://www.w3.org/XML/1998/namespace}lang"/>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "TaxDescriptionType", propOrder = {
"shortName"
})
public class TaxDescriptionType {
@XmlElement(name = "ShortName", required = true)
protected String shortName;
@XmlAttribute(name = "lang", namespace = "http://www.w3.org/XML/1998/namespace")
@XmlJavaTypeAdapter(CollapsedStringAdapter.class)
@XmlSchemaType(name = "NCName")
protected String lang;
/**
* Gets the value of the shortName property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getShortName() {
return shortName;
}
/**
* Sets the value of the shortName property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setShortName(String value) {
this.shortName = value;
}
/**
* Gets the value of the lang property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getLang() {
return lang;
}
/**
* Sets the value of the lang property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setLang(String value) {
this.lang = value;
}
}
Luego, con la class
anterior class
puedo trabajar con los elementos como este:
taxDescriptionType.setLang("en");
taxDescriptionType.setShortName("vatspecial");
/* missing value: 17.5% Non-Recoverable */
Pero el problema es que no puedo encontrar una forma de get
o set
el 17.5% Non-Recoverable
texto 17.5% Non-Recoverable
de MixedContent-ComplexType
en el ejemplo XML
anterior.
Esto es lo que intenté y no está funcionando:
- Se usa el atributo
mixed="true"
como este:
<xsd:complexType name="TaxDescriptionType" mixed="true">
(Creo que XJC está ignorando el último atributo)
Investigando un poco, encontré esto:
Compilador JAXB XJC sin tener en cuenta mixed = true en documentos de esquema XML
Pero no estoy seguro de si esta es la manera de resolver esto. Una de las respuestas dice que se trata de un error y en el otro muestra un código que transforma MixedContent
en una List<Serializable>
y tal vez la siguiente situación sea sobre cómo lidiar con esto:
taxDescriptionType.getContent().add(Serializable element);
(Y realmente no sé cómo lidiar con un elemento Serializable
)
Con mixed = true, en ObjectFactory debería haber una función como JAXBElement<ShortNameType> createTaxDescriptionTypeShortNameType(ShortNameType)
, que genera el elemento serializable para usted.
@XmlElementDecl(namespace = "", name = "shortnametype", scope = TaxDescriptionType.class)
public JAXBElement<ShortNameType> createTaxDescriptionTypeShortNameType(ShortNameType value) {
return new JAXBElement<ShortNameType>(new QName("", "shortnametype"), ShortNameType.class, TaxDescriptionType.class, value);
}