【问题标题】:Load EMF model instance from XMI file从 XMI 文件加载 EMF 模型实例
【发布时间】:2015-01-12 16:21:35
【问题描述】:

我知道有几个关于这个主题的 QnA。我尝试了很多解决方案,我总是遇到同样的错误。

我的代码结构是这样的:

Resource.Factory.Registry reg = Resource.Factory.Registry.INSTANCE;
    Map<String, Object> m = reg.getExtensionToFactoryMap();
    m.put("xmi", new XMIResourceFactoryImpl());

    ResourceSet resSet = new ResourceSetImpl();
    Resource resource = resSet.getResource(URI.createURI("model/List.xmi"), true);
    resource.load(Collections.EMPTY_MAP);
    EObject root = resource.getContents().get(0);

错误:

线程“主”org.eclipse.emf.ecore.resource.impl.ResourceSetImpl$1DiagnosticWrappedException 中的异常:org.eclipse.emf.ecore.xmi.PackageNotFoundException:找不到带有 uri 'List' 的包。 (file:///C:/Users/2/My%20Repository/UNIT%20Research%20and%20Development/com.unitbilisim.research.transformation/model/List.xmi, 6, 40) 在 org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.handleDemandLoadException(ResourceSetImpl.java:319) 在 org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.demandLoadHelper(ResourceSetImpl.java:278) 在 org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.getResource(ResourceSetImpl.java:406) 在 com.unitbilisim.research.transformation.ConvertEcore2Graph.main(ConvertEcore2Graph.java:61) 原因:org.eclipse.emf.ecore.xmi.PackageNotFoundException:找不到带有 uri 'List' 的包。 (file:///C:/Users/2/My%20Repository/UNIT%20Research%20and%20Development/com.unitbilisim.research.transformation/model/List.xmi, 6, 40) 在 org.eclipse.emf.ecore.xmi.impl.XMLHandler.getPackageForURI(XMLHandler.java:2625) 在 org.eclipse.emf.ecore.xmi.impl.XMLHandler.getFactoryForPrefix(XMLHandler.java:2458) 在 org.eclipse.emf.ecore.xmi.impl.XMLHandler.createObjectByType(XMLHandler.java:1335) 在 org.eclipse.emf.ecore.xmi.impl.XMLHandler.createTopObject(XMLHandler.java:1504) 在 org.eclipse.emf.ecore.xmi.impl.XMLHandler.processElement(XMLHandler.java:1026) 在 org.eclipse.emf.ecore.xmi.impl.XMIHandler.processElement(XMIHandler.java:77) 在 org.eclipse.emf.ecore.xmi.impl.XMLHandler.startElement(XMLHandler.java:1008) 在 org.eclipse.emf.ecore.xmi.impl.XMLHandler.startElement(XMLHandler.java:719) 在 org.eclipse.emf.ecore.xmi.impl.XMIHandler.startElement(XMIHandler.java:163) 在 com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(未知来源) 在 com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator.startElement(未知来源) 在 com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(未知来源) 在 com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$ContentDriver.scanRootElementHook(未知来源) 在 com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(未知来源) 在 com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(未知来源) 在 com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(未知来源) 在 com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(未知来源) 在 com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(未知来源) 在 com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(未知来源) 在 com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(未知来源) 在 com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(未知来源) 在 com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(未知来源) 在 com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl.parse(未知来源) 在 org.eclipse.emf.ecore.xmi.impl.XMLLoadImpl.load(XMLLoadImpl.java:175) 在 org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl.doLoad(XMLResourceImpl.java:261) 在 org.eclipse.emf.ecore.resource.impl.ResourceImpl.load(ResourceImpl.java:1518) 在 org.eclipse.emf.ecore.resource.impl.ResourceImpl.load(ResourceImpl.java:1297) 在 org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.demandLoad(ResourceSetImpl.java:259) 在 org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.demandLoadHelper(ResourceSetImpl.java:274) ... 2 更多

“未找到带有 uri 的包”是什么意思?我可以直接读取 xmi 文件还是需要将其解析为 xml 文件?

我也试过这个 -> https://stackoverflow.com/a/4615965/1604503

    XMIResource resource = new XMIResourceImpl(URI.createURI("model/List.xmi"));
    resource.load(null);
    System.out.println( resource.getContents().get(0) );

PackageNotFoundEx。和 Reource$IOWrappedEx。再次:(

请帮忙

亲切的问候

【问题讨论】:

    标签: java model emf xmi ecore


    【解决方案1】:

    原因是,我没有生成模型代码。因此,无法找到“列表”包。我确实将它添加到我的 packageRegistry 中,仅此而已。

            ResourceSet resourceSet = new ResourceSetImpl();
    
            // register UML
            Map packageRegistry = resourceSet.getPackageRegistry();
            packageRegistry.put(list.ListPackage.eNS_URI, list.ListPackage.eINSTANCE);
    
            // Register XML resource as UMLResource.Factory.Instance
            Map extensionFactoryMap = Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap();
            extensionFactoryMap.put("xmi", new XMIResourceFactoryImpl());
    
            Resource resource = (Resource) resourceSet.createResource(uri);
    
    
            // try to load the file into resource
            resource.load(null);
    

    【讨论】:

      【解决方案2】:

      您应该使用 URI.createFileURI(absolutePathUri) 而不是 URI.createURI(uri)。 此外,您的模型实例(在您的情况下是 List.xmi 文件)必须具有 xsi:schemaLocation 属性以及元模型的相对路径,以避免预注册元模型包。非常重要的注意事项:您的 uri 参数必须由模型的绝对路径构建

      Kotlin 语言示例:

          Resource.Factory.Registry.INSTANCE.extensionToFactoryMap.apply {
              put("ecore", EcoreResourceFactoryImpl())
              put("xmi", XMIResourceFactoryImpl())
          }
      
          val resourceSet = ResourceSetImpl()
      
          // createFileURI method is able to locate metamodel by xsi:schemaLocation
          // absolute path is important here !!!
          val resource = resourceSet.getResource(URI.createFileURI(File(modelPath).absolutePath), true)
          resource.allContents.forEach { eObj ->
              //do smth
          }
      

      动态EPackage的预注册参考eclipse wiki

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-21
        • 2012-04-04
        • 1970-01-01
        • 2010-11-16
        • 1970-01-01
        • 2018-07-08
        相关资源
        最近更新 更多