1

我正在使用 Eclipse 建模框架 (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 架构中定义的类型;我可以实例化生成的XMLFileJava 对象,它具有对Version我也可以实例化的对象的引用。它甚至有对 的引用AdditionalInformation,但是因为AdditionalInformation已经xs:anyType在 XSD 模式中声明了类型,所以AdditionalInformationXMLFile指向的引用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-hierarchies 转换为 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徒劳无功。

4

0 回答 0