【问题标题】:How to programmatically generate an EMF model (.ecore, .genmodel) from XSD schema?如何以编程方式从 XSD 模式生成 EMF 模型(.ecore、.genmodel)?
【发布时间】:2010-11-16 23:43:09
【问题描述】:

我一直在尝试将此作为独立应用程序的最后一个阶段,以将建模程序使用的文件格式转换为 EMF 模型。我能够将原始格式转换为 XSD,我可以使用 Eclipse 导入器手动将其转换为 EMF 模型,但我不知道如何以编程方式执行此操作以自动化该过程。 Java 命令可以正常工作,任何命令行语句都可以,因为我可以在 Java 中执行该语句。我花了一段时间寻找如何做到这一点,尝试http://wiki.eclipse.org/Generating_Dynamic_Ecore_from_XML_Schema 和各种其他潜在的解决方案,但似乎没有任何效果。如果有人能够提供一些关于如何从 XSD 文件生成 .ecore 和(/或?) .genmodel 文件的示例代码,我将非常感激,但甚至可以提供一些关于如何继续的指导会很有帮助。

谢谢。

【问题讨论】:

    标签: java xsd eclipse-emf


    【解决方案1】:

    查看org.eclipse.xsd.ecore.XSDEcoreBuilder 类以及 Eclipse 导入器向导使用它的方式。
    似乎使用起来相当简单,您只需调用它的 generate 方法之一,即可返回 Collection<Resource>Collection<EObject>

    (编辑:在 cmets 中回答其他问题)
    EPackage 类是 xs:schema 的 Ecore 等价物,其中包含 EClasses,它们又是 xs:complexTypes 的 Ecore 等价物。

    以下代码 sn-p 应该创建一个 foo.ecore 文件并将其保存到与源 XSD 相同的文件夹中。如果 foo.xsd 有其他导入的 XSD,它们将被转换为单独的 .ecore 文件,因此返回类型为 Collection<Resource>

    URI schemaURI = URI.createFileURI("foo.xsd");
    Collection<Resource> ecoreResources = XSDEcoreBuilder.generateResources(schemaURI);
    for (Resource ecoreResource : ecoreResources) {
        ecoreResource.save(null);
    }
    

    【讨论】:

    • 查看 Eclipse 源代码通常是找到此类问题答案的最佳方式。您在 wiki 或 Eclipse 新闻组中找到的内容通常已过时。
    • 我尝试通过 Eclipse XSD 导入器查看它如何使用 XSDEcoreBuilder。它似乎做了类似的事情,产生了一个 EPackage 列表。 wiki.eclipse.org/Generating_Dynamic_Ecore_from_XML_Schema 中的集合也是一个 EPackage 列表,我相信,因为下面的代码遍历集合以获取每个单独的 EPackage。但是,我不明白,您如何使用此 EPackage 来获取它,例如,这些 .ecore 或 .genmodel 格式之一,或者根本如何阅读它。即,我该如何处理这个 EPackage?很抱歉这么无知。
    • 尝试调用 generateResources 会导致运行时错误:org.eclipse.xsd.ecore.XSDEcoreBuilder.generateResources(XSDEcoreBuild er.java:2765) 处的线程“main”java.lang.NullPointerException 异常.eclipse.xsd.ecore.XSDEcoreBuilder.generateResources(XSDEcoreBuild er.java:2742) at ... 调用 generate 而不是 generateResources 似乎有效;不过,它会生成一个 EPackage 而不是 Resource,但我不知道如何保存它。我尝试查看 generateResources 代码并在我的代码中模拟它,但我无法访问所有方法。不过感谢您的帮助;看起来更近了。
    • 作为更新,我认为确切的问题是“Resource ecoreResource = resourceSet.createResource(URI.createURI("*.ecore"));”在 generateResources 中以 ecoreResource 仍然为空结束。至少,这是我通过查看 Eclipse 源代码尝试在我的代码中重新创建该方法所确定的。不过,这可能只是我的代码仿真中的一个问题或误解;我真的不知道在这一点上。我想如果可以将 EPackage 转换为 ecore 会更容易,但我也不知道这是否可能。或者是否可以在这里确定问题。
    • 关于该问题的任何新信息? XSDEcoreBuilder 似乎不再有一个名为 generateResources 的方法
    【解决方案2】:

    上述代码使用以下设置在这里工作:

    版本:Luna Service Release 2 (4.4.2) 内部版本号:20150219-0600

    插件:

    • ATL SDK - ATLAS 转换语言 SDK 3.5.0.v201405260755 org.eclipse.m2m.atl.sdk.feature.group
    • Eclipse 建模项目 Eclipse 建模工具 4.4.2.20150219-0708 epp.package.modeling
    • 用于 Ecore 1.4.0 fr.irisa.triskell.kermeta.ecore.feature.group IRISA/INRIA 的 Kermeta MDK
    • OCL 示例和编辑器 SDK 3.4.4.v20150213-2254 org.eclipse.ocl.examples.feature.group
    • Eclipse 建模项目
    • Xtext Complete SDK 2.7.3.v201411190455 org.eclipse.xtext.sdk.feature.group Eclipse 建模项目

    但是,初始 XSD 文件会被 Ecore 内容覆盖。此外,save 操作被调用两次(一次用于XSDResourceImpl,一次用于EcoreResourceFactoryImpl)。我们只需要EcoreResourceFactoryImpl。为了解决这个问题,这里是示例代码:

        URI schemaURI = URI.createFileURI("library3.xsd");
        File outputFile = new File("library3.ecore");
        XSDEcoreBuilder xsdEcoreBuilder = new XSDEcoreBuilder(); 
        Collection<Resource> ecoreResources = xsdEcoreBuilder.generateResources(schemaURI);
    
        // for every resource found (includes eventually referenced XSDs)
        for (Resource ecoreResource : ecoreResources) {
            try {
                if (ecoreResource.getClass().getName().contains("EcoreResourceFactoryImpl")) {
                    ecoreResource.save(new FileOutputStream(outputFile), null);
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    

    【讨论】:

      猜你喜欢
      • 2010-10-30
      • 2012-03-12
      • 2014-05-07
      • 2011-06-18
      • 2012-01-25
      • 2011-08-28
      • 2018-06-30
      • 1970-01-01
      • 2014-07-03
      相关资源
      最近更新 更多