Я сталкиваюсь с проблемой маршаллинга / демаршаллинга, связанной с наследованием и полиморфизмом, с использованием реализации JAXB MOXy и файла привязок внешних метаданных.
У меня нет контроля над файлами XML или классами модели.* Внутри модели есть несколько классов, которые наследуют другие классы DTO.Вот пример среды, в которой я работаю. Этот пример приведен здесь только для некоторой синтаксической цели, реальная среда включает вложенное наследование, коллекции и т. Д.:
Вот класс, который будет унаследован
class A {
private String name;
public String getName(){
return name;
}
public void setName(String value){
name = value;
}
}
Вот один унаследованный класс
class B extends A {
private String attrFromB;
public String getAttrFromB(){
return attrFromB;
}
public void setAttrFromB(String value){
attrFromB = value;
}
}
И еще один
class C extends A {
private String attrFromC;
public String getAttrFromC(){
return attrFromC;
}
public void setAttrFromC(String value){
attrFromC= value;
}
}
Вот контейнерный класс
class MyContainerClass{
private A myObject;
public A getMyObject(){
return myObject;
}
public void setMyObject(A value){
myObject = value;
}
}
Вот XMLчто он должен производить в случае MyContainer, содержащего A
<MyContainer>
<MyObject nameA="foo" />
</MyContainer>
MyContainer, содержащего B
<MyContainer>
<MyObject nameB="foo" attrFromB="bar" />
</MyContainer>
, и MyContainer, содержащего C
<MyContainer>
<MyObject nameC="foo" attrFromC="bar" />
</MyContainer>
Так что вы уже можете видетьпроблемы на горизонте ...
Вот файл сопоставления, который я написал бы:
<?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>
Первая проблема заключается в том, что если я связываю классы таким образом, я получаюследующее исключение:
[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()].
1-й вопрос : Я понимаю, что это нормально, Jaxb нужен какой-то способ определить тип атрибута MyContaioner.myObject.Проблема в том, что у меня нет доступа к входящим XML-файлам, поэтому я не могу добавить к ним поля типа xsi: type.Есть ли способ определить класс на основе наличия в нем определенного атрибута?независимо от его стоимости.Если исходный xml содержит атрибут @attrFromC, я знаю, что объект должен иметь тип C. Если он содержит attrFromB, это B.
Вторая проблема заключается в том, что атрибут name несуществуют внутри B и C, поэтому jaxb игнорирует их.
--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.
2-й вопрос : Другая проблема заключается в том, что я не знаю, способен ли Jaxb переопределять имена атрибутов xml так, как ожидаетсявнутри файла XML (@nameA, @nameB и nameC все ссылаются на A.name), есть ли способ сделать это?
Заранее спасибо за ваше время.