Импорт элементов AnyType в EMF
Я строю импортер XML с использованием Eclipse Modeling Framework (EMF). Для этого я заставил EMF сгенерировать мне модель Ecore из моей метамодели XSD и сгенерировать соответствующие Java-классы из модели Ecore. Сейчас я читаю в файле XML, соответствующем моей схеме XSD, и застрял в следующей проблеме: Создание экземпляров объектов для всех типов, определенных в схеме XSD, работает отлично, и я получаю хорошую иерархию Java-объектов (экземпляров), но я могу не удается создать экземпляры элементов AnyType. Скажем, у меня есть следующий XML:
<XMLFile xsi:noNamespaceSchemaLocation="My_xsd_file.xsd" FileName="Example.xml" SchemaVersion="1.10" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Version>2.1</Version>
<AdditionalInformation someAttribute="someValue" />
<AdditionalInformation>
<SomeChildElement>
<ChildA>Some content</ChildA>
<ChildB>Some content</ChildB>
</SomeChildElement>
</AdditionalInformation>
</XMLFile>
XMLFile
а также Version
типы, определенные в схеме XSD; Я могу создать экземпляр сгенерированного XMLFile
Java-объект, он имеет ссылку на Version
объект, который я тоже могу создать. Это даже имеет ссылку на AdditionalInformation
, но потому что AdditionalInformation
был объявлен типа xs:anyType
в схеме XSD ссылка AdditionalInformation
из XMLFile
указывает на EObject
который сам по себе не имеет ссылок (поэтому я не могу добавить его дочерние элементы к нему), и нельзя добавлять ссылки на EObject
, Вот мой код для установки этих ссылок:
for (EReference reference : object.eClass().getEAllReferences()) {
if (reference.getName().toLowerCase().equals(childNode.getNodeName().toLowerCase())) {
EClass type = Utils.getInstantiableEClass(reference.getEReferenceType());
if (type != null && reference.isChangeable()) {
if (reference.isMany()) {
EList list = (EList)object.eGet(reference);
EObject obj = EcoreUtil.create(type);
if(obj.getClass().equals(EObjectImpl.class)) {
obj = xmlFactory.createAnyType();
}
//recursiveImport(childNode, obj);
list.add(obj);
...
Поэтому, когда я заметил, что это не работает с EObjects, я создаю AnyType
вместо объекта (см. код выше), так как в этой статье говорится, что для этого предназначены объекты AnyType. Тем не менее, я не могу установить AnyType
ссылки на объект либо:
if (object instanceof AnyType) {
NodeList children = node.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node childNode = children.item(i);
switch (childNode.getNodeType()) {
case Node.ELEMENT_NODE:
AnyType childObj = xmlFactory.createAnyType();
recursiveImport(childNode, childObj);
Entry entry = FeatureMapUtil.createEntry(xmlPackage.getAnyType_Any(), childObj);
((FeatureMap) object.eGet(xmlPackage.getAnyType_Any())).add(entry); // throws exception
((AnyType) object).getAny().add(entry); // throws exception
...
Это создает исключение:
Exception in thread "main" java.lang.ClassCastException: The feature 'any's type 'EFeatureMapEntry' does not permit a value of type 'AnyType'
at org.eclipse.emf.ecore.impl.EStructuralFeatureImpl$BasicFeatureMapEntry.validate(EStructuralFeatureImpl.java:3213)
at org.eclipse.emf.ecore.util.FeatureMapUtil.createEntry(FeatureMapUtil.java:174)
Я сбит с толку. Разве не AnyType
объект должен делать именно это? Разрешить произвольное количество AnyType
дети? Знаете ли вы, как превратить XML-иерархии anyType в сгенерированные EMF экземпляры Java?
PS: я прочитал https://www.eclipse.org/forums/index.php/t/536670/ и http://www.eclipse.org/modeling/emf/docs/presentations/EclipseCon/EclipseCon2006_EMF_XML_Binding.pdf, чтобы безрезультатно.