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:
- Read XML,
- Get the values into objects. 开发者_开发问答
- Use ORM to persist the values in objects to database. - Done
- 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.
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);
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:
- Create an empty EMF Project.
- Create a simple Ecore file (.ecore), or get it from the Internet. Or import from any XML Schema/UML file into an Ecore model.
- Right click on an EClass then "Create Dynamic Instance", this will create an .xmi file.
- Open the .xmi file, using Eclipse, this will open the EMF Editor for that model. Edit as you see fit.
- 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) );
I built a small program that does some basic model format conversion using emftriple (former emf4sw), i.e. Ecore XMI (XML file) to RDF TTL.
I used some of the tips in the answers here, so thank you guys!
Maybe the source code can inspire you: https://github.com/frostyandy2k/model-transformer
The normal way to do this kind of thing is to start with an XML schema, then use this to generate the EMF model, and then generate Java code. This is describe in this EMF tutorial.
You don't need to implement read/write methods. Rather you make use of EMF library code to do the XML import and export. I don't have my copy of the EMF book in front of me right now, but it is covered in there. Alternatively, take a look at what the generated EMF editor does when you load or save a model instance.
EDIT
Here is a resource utility class from an EMF-based project I developed a couple of years ago. Look at the load*
methods. Note that this is not necessarily the best way to do this ... but it worked for me.
EDIT 2
I just realised that I was using XMI not plain XML. Configuring an XML reader with a custom schema and (potentially) a customized schema mapping is likely to be different. So, returning to my original answer, look at the generated code!!.
EMF is not designed to read arbitrary XML files. EMF uses XML as a backend. Where do your XML files come from/which schema do they conform to? If you have the schema, then you can use it to create an EMF model, which in turn is hopefully able to read your XML files.
Otherwise you would have to reverse engineer an EMF model that would indeed serialize to your XML, so that you'd be able to read it, but that would be a hack.
After UPDATE2:
I guess the next question then is "What problem do you have with loading your files". How do you do it, and what is not working? Or you don't know how to do it?
You first have to configure the factory for your resource set (the in-memory representation of the set of files that you want to work with), and then load the file with getResource(URI, bool). Example for some UML stuff I'm doing:
resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put(UMLResource.FILE_EXTENSION, UMLResource.Factory.INSTANCE);
resourceSet.getPackageRegistry().put("http://www.eclipse.org/uml2/2.0.0/UML", UMLPackage.eINSTANCE);
Resource r = resourceSet.getResource(uriToYourFile,true);
YourModelRootType root = (YourModelRootType) r.getContents().get(0);
That should all be covered in the tutorial that you already have the link to. Then, you can use the generated Java API to work from 'root'.
I have no experience with the ORM-stuff, though, but maybe you should take a look at CDO.
精彩评论