Estoy enfrentando un problema de marshalling/unmarshalling que implica herencia y polimorfismo utilizando la implementación JAXB de MOXy y el archivo de enlaces de metadatos externos.eclipselink/Moxy: herencia y nombre de atributo oveloading basado en el tipo
No tengo control sobre los archivos XML o las clases de modelo.
Hay varias clases dentro del modelo que heredan otras clases de DTO. . Aquí se muestra un ejemplo del medio ambiente que estoy trabajando en este ejemplo es sólo aquí con un propósito de sintaxis, el entorno real implica la herencia anidada, etc. colecciones:
Aquí está la clase que se hereda
class A {
private String name;
public String getName(){
return name;
}
public void setName(String value){
name = value;
}
}
Aquí es una clase heredada
class B extends A {
private String attrFromB;
public String getAttrFromB(){
return attrFromB;
}
public void setAttrFromB(String value){
attrFromB = value;
}
}
Y otra
class C extends A {
private String attrFromC;
public String getAttrFromC(){
return attrFromC;
}
public void setAttrFromC(String value){
attrFromC= value;
}
}
Aquí está una clase de contenedor
class MyContainerClass{
private A myObject;
public A getMyObject(){
return myObject;
}
public void setMyObject(A value){
myObject = value;
}
}
Aquí es el XML que se debe producir en el caso de MyContainer que contiene A MyContainer
<MyContainer>
<MyObject nameA="foo" />
</MyContainer>
contiene B
<MyContainer>
<MyObject nameB="foo" attrFromB="bar" />
</MyContainer>
Y MyContainer que contiene C
<MyContainer>
<MyObject nameC="foo" attrFromC="bar" />
</MyContainer>
Así que ya se puede ver problemas en el horizonte ...
Aquí está el archivo de asignación que escribiría:
<?xml version="1.0"?>
<xml-bindings
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
package-name="com.test.example"
version="2.1">
<java-type name="A" xml-accessor-type="NONE">
<xml-root-element name="MyObject" />
<java-attributes>
<xml-element java-attribute="name" xml-path="@nameA" />
</java-attributes>
</java-type>
<java-type name="B" xml-accessor-type="NONE">
<xml-root-element name="MyObject" />
<xml-see-also>
com.test.example.A
</xml.see.also>
<java-attributes>
<xml-element java-attribute="name" xml-path="@nameB" />
<xml-element java-attribute="attrFromB" xml-path="@attrFromB" />
</java-attributes>
</java-type>
<java-type name="C" xml-accessor-type="NONE">
<xml-root-element name="MyObject" />
<xml-see-also>
com.test.example.A
</xml.see.also>
<java-attributes>
<xml-element java-attribute="name" xml-path="@nameC" />
<xml-element java-attribute="attrFromC" xml-path="@attrFromC" />
</java-attributes>
</java-type>
<java-type name="MyContainer" xml-accessor-type="NONE">
<xml-root-element name="MyContainer" />
<java-attributes>
<xml-element java-attribute="myObject" type="com.test.example.A" xml-path="MyObject" />
</java-attributes>
</java-type>
</xml-bindings>
El primer problema es que si me ato las clases como que, tengo la siguiente excepción:
[Exception [EclipseLink-44] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: Missing class indicator field from database row [UnmarshalRecord()].
primera pregunta: entiendo que esto es normal , Jaxb necesita alguna forma de determinar el tipo de atributo MyContaioner.myObject. El problema es que no tengo acceso a los archivos XML entrantes, así que no puedo agregar xsi: escriba campos para ellos. ¿Hay alguna forma de determinar una clase basada en la presencia de un atributo específico en ella? independientemente de su valor. Si el código fuente XML contiene un atributo @attrFromC, sé que el objeto debe ser de tipo C. Si contiene attrFromB, es B.
El segundo problema es que el atributo "name" no existe en el interior B y C, entonces jaxb los ignora.
--Ignoring attribute [name] on class [com.test.example.B] as no Property was generated for it.
--Ignoring attribute [name] on class [com.test.example.C] as no Property was generated for it.
segunda pregunta: El otro problema es que no sé si JAXB es capaz de anular xml nombres de atributo como se espera dentro del archivo XML (@nameA, @nameB y NAMEC todo lo referente a A. nombre), ¿hay alguna manera de hacerlo?
Gracias de antemano por su tiempo.
La lectura de la primera parte de su respuesta, esto ya está siendo realmente útil. Gracias. No puedo esperar para la segunda parte. – Drewman
Solo para estar seguro, si dentro de ClassExtractor, quiero probar la presencia de un nodo y no un atributo. ¿Puedo usar record.get ("SomeNodeName") o record.get ("SomeNodeName/text()")? – Drewman
@ user1121108 - He agregado una respuesta para la segunda parte. En el extractor de clases, solo podrás probar la presencia de atributos. En ese punto de la ejecución, los elementos secundarios aún no se han procesado. –