У меня есть XML-схема с абстрактным типом, похожая на эту:
<xs:complexType name="AbstractFinancialAnalysis" abstract="true">
<xs:sequence>
<xs:element name="comment" type="xs:string" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="currency" type="enums:Currency" use="optional"/>
<xs:attribute name="statement_date" type="xs:date" use="required"/>
</xs:complexType>
<xs:complexType name="FinancialAnalysisUG">
<xs:complexContent>
<xs:extension base="AbstractFinancialAnalysis">
<xs:sequence>
<!-- some elements -->
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="FinancialAnalysisKP">
<xs:complexContent>
<xs:extension base="AbstractFinancialAnalysis">
<xs:sequence>
<!-- some elements -->
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="FinancialAnalysisIB">
<xs:complexContent>
<xs:extension base="AbstractFinancialAnalysis">
<xs:sequence>
<!-- some elements -->
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="FinancialAnalysisWrapper">
<xs:sequence>
<xs:element name="xml_data" type="fadata:AbstractFinancialAnalysis" />
</xs:sequence>
<!-- some attributes -->
</xs:complexType>
<xs:element name="financial_analysis_response">
<xs:complexType>
<xs:sequence>
<xs:element name="financial_analysis" type="FinancialAnalysisWrapper" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
Созданы классы Java, такие как:
// ----- ObjectFactory.java ----- //
@XmlRegistry
public class ObjectFactory {
private final static QName _FinancialAnalysisUg_QNAME = new QName("http://rsnag.ch/cm/FinancialAnalysisWrapper/Main-6", "financial_analysis_ug");
private final static QName _FinancialAnalysisIb_QNAME = new QName("http://rsnag.ch/cm/FinancialAnalysisWrapper/Main-6", "financial_analysis_ib");
private final static QName _FinancialAnalysisKp_QNAME = new QName("http://rsnag.ch/cm/FinancialAnalysisWrapper/Main-6", "financial_analysis_kp");
public FinancialAnalysisResponse createFinancialAnalysisResponse() {
return new FinancialAnalysisResponse();
}
public AbstractFinancialAnalysis createFinancialAnalysisIB() {
return new FinancialAnalysisIB();
}
public AbstractFinancialAnalysis createFinancialAnalysisKP() {
return new FinancialAnalysisKP();
}
public AbstractFinancialAnalysis createFinancialAnalysisUG() {
return new FinancialAnalysisUG();
}
@XmlElementDecl(namespace = "http://rsnag.ch/cm/FinancialAnalysisWrapper/Main-6", name = "financial_analysis_ug")
public JAXBElement<FinancialAnalysisUG> createFinancialAnalysisUg(FinancialAnalysisUG value) {
return new JAXBElement<>(_FinancialAnalysisUg_QNAME, FinancialAnalysisUG.class, null, value);
}
@XmlElementDecl(namespace = "http://rsnag.ch/cm/FinancialAnalysisWrapper/Main-6", name = "financial_analysis_ib")
public JAXBElement<FinancialAnalysisIB> createFinancialAnalysisIb(FinancialAnalysisIB value) {
return new JAXBElement<>(_FinancialAnalysisIb_QNAME, FinancialAnalysisIB.class, null, value);
}
@XmlElementDecl(namespace = "http://rsnag.ch/cm/FinancialAnalysisWrapper/Main-6", name = "financial_analysis_kp")
public JAXBElement<FinancialAnalysisKP> createFinancialAnalysisKp(FinancialAnalysisKP value) {
return new JAXBElement<>(_FinancialAnalysisKp_QNAME, FinancialAnalysisKP.class, null, value);
}
}
// ----- FinancialAnalysisResponse.java ----- //
@XmlRootElement(name = "financial_analysis_response", namespace = "http://rsnag.ch/cm/ExportFinancialAnalysis/Response-8")
@XmlAccessorType(XmlAccessType.FIELD)
public class FinancialAnalysisResponse {
@XmlElement(name = "financial_analysis")
private List<FinancialAnalysisWrapper> financialAnalyses;
// attributes
// getters and setters
}
// ----- FinancialAnalysisWrapper.java ----- //
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class FinancialAnalysisWrapper {
@XmlElement(name = "xml_data", required = true)
private AbstractFinancialAnalysis financialAnalysisData;
// attributes
// getters and setters
}
// ----- AbstractFinancialAnalysis.java ----- //
@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso({
FinancialAnalysisKP.class,
FinancialAnalysisIB.class,
FinancialAnalysisUG.class
})
public abstract class AbstractFinancialAnalysis {
// elements and attributes
// getters and setters
}
// ----- FinancialAnalysisIB.java ----- //
@XmlRootElement
@XmlType(name = "FinancialAnalysisIB")
@XmlAccessorType(XmlAccessType.FIELD)
public class FinancialAnalysisIB extends AbstractFinancialAnalysis {
// elements
// getters and setters
}
// ----- FinancialAnalysisKP.java ----- //
@XmlRootElement
@XmlType(name = "FinancialAnalysisKP")
@XmlAccessorType(XmlAccessType.FIELD)
public class FinancialAnalysisKP extends AbstractFinancialAnalysis {
// elements
// getters and setters
}
// ----- FinancialAnalysisUG.java ----- //
@XmlRootElement
@XmlType(name = "FinancialAnalysisUG")
@XmlAccessorType(XmlAccessType.FIELD)
public class FinancialAnalysisUG extends AbstractFinancialAnalysis {
// elements
// getters and setters
}
Насколько мне известно и исследования в Интернете ( источник ), JAXB должен иметь возможность решить, какая реализация абстрактного типа используется на основе атрибута xsi:type
(который присутствует).
Но во время демаршаллинга я получаю ошибку:
[com.sun.istack.SAXParseException2; lineNumber: 1; columnNumber: 608; Unable to create an instance of com.example.application.entity.jaxb.AbstractFinancialAnalysis
Я также пробовал такие вещи, как:
@XmlElements({...})
на элементе xml_data
, например this . Он почти работал, но никогда не выбирал правильную реализацию абстрактного класса.
@XmlTransient
для абстрактного класса, например this . Я понял, что это для чего-то другого.
Может кто-нибудь объяснить, что я делаю не так? Спасибо
EDIT
Я обнаружил эту открытую проблему на github Возможно, я столкнулся с той же проблемой.