我正在使用Eclipse Modeling Framework(EMF)构建XML导入器。为此,我让EMF从我的XSD元模型生成一个Ecore模型,并从Ecore模型生成相应的Java类。现在我正在读取符合我的XSD架构的XML文件并遇到以下问题:为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
已在XSD架构中声明为xs:anyType
类型,因此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
对象(参见上面的代码),因为this article表示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实例吗?
P.S。:我读过https://www.eclipse.org/forums/index.php/t/536670/和http://www.eclipse.org/modeling/emf/docs/presentations/EclipseCon/EclipseCon2006_EMF_XML_Binding.pdf,但没有用。