Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use EMF to read XML file?

EMF = Eclipse Modeling Framework

I have to use EMF in one of my class projects. I am trying to understand how to use EMF to do the following:

  1. Read XML,
  2. Get the values into objects.
  3. Use ORM to persist the values in objects to database. - Done
  4. Get data from database using ORM and generate XML.

I need to do all of that using: EMF (no idea what so ever) and JPA (DONE).

I have used JAXB and I know, this can be done using JAXB, but how is (EMF == JAXB)?!

I have created many java classes using EMF, but there are so many of them! Where do I implement the read/write methods and how do I run the EMF project?

Thanks

UPDATE1 HINT http://www.eclipsezone.com/eclipse/forums/t58829.html

UPDATE2

I have schema and I have generated the model code using the .xsd. Now I am having problem in reading the data from the XML file.

like image 413
zengr Avatar asked Mar 30 '10 09:03

zengr


2 Answers

You can read arbitrary XML files with EMF, provided you have the XSD for them, and you don't even have to generate Java classes from the XSD.
I blogged about this a couple of months ago, but I will paste the code snippets here as well. For a slightly more detailed explanation see my blog post on How to load and compare arbitrary XML files with EMF.

First you need to load the XSD and initialize a couple of things:

// generate EPackages from schemas
XSDEcoreBuilder xsdEcoreBuilder = new XSDEcoreBuilder();
Collection generatedPackages = xsdEcoreBuilder.generate(schemaURI);

// register the packages loaded from XSD
for (EObject generatedEObject : generatedPackages) {
    if (generatedEObject instanceof EPackage) {
        EPackage generatedPackage = (EPackage) generatedEObject;
        EPackage.Registry.INSTANCE.put(generatedPackage.getNsURI(),
            generatedPackage);
    }
}

// add file extension to registry
ResourceFactoryRegistryImpl.INSTANCE.getExtensionToFactoryMap()
    .put(MY_FILE_EXTENSION, new GenericXMLResourceFactoryImpl());

After that you can load your XML files like you would normally do:

ResourceSet resourceSet = ResourceSetFactory.createResourceSet();
Resource resource = resourceSet.getResource(xmlURI, true);
resource.load(Collections.EMPTY_MAP);
EObject root = resource.getContents().get(0);
like image 100
Zsolt Török Avatar answered Sep 30 '22 06:09

Zsolt Török


EMF serializes the data model using (the default, most popular way) XMIResourceImpl, which strictly uses the XMI format, and not a custom XML structure.

See http://eclipsedriven.blogspot.com/ for articles about EMF and its use cases.

I agree with other answerers that EMF is probably not what you want here.

If I really want to use EMF with a custom XML structure (i.e. not XMI), I'd probably use JAXB to marshal/unmarshal my EMF objects (EObjects).

So EMF is not the same as JAXB and they have different purposes and goals. In fact you probably can combine EMF and JAXB in some way. I've never tried it, but it seems there are valid uses cases. (as I said above, for marshaling/unmarshaling EMF objects to/from XML)

To understand EMF you need to switch your paradigm. For a start remove the "XML" part, let it go from your mind. Then I suggest you to do the following:

  1. Create an empty EMF Project.
  2. Create a simple Ecore file (.ecore), or get it from the Internet. Or import from any XML Schema/UML file into an Ecore model.
  3. Right click on an EClass then "Create Dynamic Instance", this will create an .xmi file.
  4. Open the .xmi file, using Eclipse, this will open the EMF Editor for that model. Edit as you see fit.
  5. Inspect the contents of the (edited) .xmi file. You'll see that the format conforms exactly to the Ecore model. You will not be able to change/customize the mapping from model <-> XMI file because, as the name implies, XMIResourceImpl only reads/saves XMI files (which happens to be implemented on top of XML) but it does not read/save arbitrary XML format.

EMF has support for reading/writing XML Schema metamodels (i.e. XSD files) for the purpose of converting them to an Ecore metamodel, but not XML files that conforms to such a schema (not even to Ecore), unless these files are in XMI format.

For persisting EMF models into a relational database, see: http://eclipsedriven.blogspot.com/2010/12/persisting-emf-objects-to-rdbms-with.html

I'm using Teneo. (and optionally, CDO)

Regarding "XML", if you stick to XMI and be content with it, EMF will make your life much easier, as you don't need to do any mapping (unlike JAXB). The downside is that our objects must be EMF Objects.

EMF Objects are objects that are generated by EMF and implements EObject and directly or indirectly extends EObjectImpl. You usually wouldn't want to code EMF Objects by hand, it would be a chore. On the other hand, JAXB "objects" are usually pure domain object POJOs and has no additional requirement from JAXB. Note that unlike JAXB, EMF Objects are not POJOs. This explains another different goal between EMF and JAXB. Their overlap is less than you'd imagine.

Reading from XMI (not XML) is very easy:

XMIResource resource = new XMIResourceImpl(URI.create("file:/path/to/mymodel.xmi"));
resource.load(null);
System.out.println( resource.eContents().get(0) );
like image 33
Hendy Irawan Avatar answered Sep 30 '22 08:09

Hendy Irawan