3
votes

I have been trying to do this as the last stage in a standalone application to convert from the file format used by a modeling program to an EMF model. I am able to convert the original format to XSD, which I can manually convert to an EMF model using the Eclipse importer, but I do not know how to do this programmatically to automate the process. Java commands would work fine, as would any command-line statement to do the same, since I could just execute the statement from within Java. I have spent a while looking for how to do this, trying http://wiki.eclipse.org/Generating_Dynamic_Ecore_from_XML_Schema and a variety of other potential solutions, but nothing seems to work. If anyone might be able to provide some sample code as to how to generate the .ecore and(/or?) .genmodel files from an XSD file, I'd very much appreciate it, but even some guidance as to how I can proceed would help very much.

Thank you.

2

2 Answers

5
votes

Take a look at the class org.eclipse.xsd.ecore.XSDEcoreBuilder and the way it's used by the Eclipse importer wizard.
Seems to be fairly straightforward to use, you simply call one of its generate methods and you get back either a Collection<Resource> or a Collection<EObject>.

(Edit: answering additional questions in comments)
The EPackage class is the Ecore equivalent of xs:schema, which contains the EClasses, which are in turn the Ecore equivalents of xs:complexTypes.

The following code snippet should create and save a foo.ecore file into the same folder as the source XSD. If foo.xsd has additional imported XSDs, they will be coverted into separate .ecore files, hence the return type Collection<Resource>.

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

The above-mentioned code works here using the following setup:

Version: Luna Service Release 2 (4.4.2) Build id: 20150219-0600

Plugins:

  • ATL SDK - ATLAS Transformation Language SDK 3.5.0.v201405260755 org.eclipse.m2m.atl.sdk.feature.group
  • Eclipse Modeling Project Eclipse Modeling Tools 4.4.2.20150219-0708 epp.package.modeling
  • Kermeta MDK for Ecore 1.4.0 fr.irisa.triskell.kermeta.ecore.feature.group IRISA/INRIA
  • OCL Examples and Editors SDK 3.4.4.v20150213-2254 org.eclipse.ocl.examples.feature.group
  • Eclipse Modeling Project
  • Xtext Complete SDK 2.7.3.v201411190455 org.eclipse.xtext.sdk.feature.group Eclipse Modeling Project

However, the initial XSD file is overwritten by the Ecore content. Also, the save operation is called twice (once for the XSDResourceImpl and once for EcoreResourceFactoryImpl). We need it only for EcoreResourceFactoryImpl. To fix this, here the sample code:

    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();
        }
    }