如何使用EMF读取XML文件?

EMF = Eclipse Modeling Framework

我必须在我的一个class级项目中使用EMF。 我试图了解如何使用EMF执行以下操作:

  1. 读XML,
  2. 将值获取到对象中。
  3. 使用ORM将对象中的值持久保存到数据库。 – 完成
  4. 使用ORM从数据库获取数据并生成XML。

我需要使用以下所有内容:EMF(不知道是什么)和JPA(DONE)。

我使用过JAXB,我知道,这可以使用JAXB完成,但是(EMF == JAXB)怎么办?!

我使用EMF创建了许多java类,但是它们有很多! 我在哪里实现读/写方法以及如何运行EMF项目?

谢谢

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

UPDATE2

我有架构,我使用.xsd生成了模型代码。 现在我在从XML文件中读取数据时遇到了问题。

EMF使用(默认的,最流行的方式)XMIResourceImpl序列化数据模型,XMIResourceImpl 严格使用XMI格式,而不是自定义XML结构

有关EMF及其用例的文章,请参见http://eclipsedriven.blogspot.com/ 。

我同意其他的回答者说EMF可能不是你想要的。

如果我真的想要使用自定义XML结构的EMF(即不是XMI),我可能会使用JAXB来编组/解组我的EMF对象(EObjects)。

因此,EMF与JAXB不同,它们有不同的目的和目标。 事实上,你可能会以某种方式结合EMF和JAXB。 我从来没有尝试过,但似乎有一些有效的用例。 (正如我上面所说的,用于将EMF对象编组到/从XML解组/解组)

要了解EMF,您需要切换范例。 首先删除“XML”部分,让它离开你的脑海。 然后我建议你做以下事情:

  1. 创建一个空的EMF项目。
  2. 创建一个简单的Ecore文件(.ecore),或从Internet获取它。 或者从任何XML Schema / UML文件导入到Ecore模型中。
  3. 右键单击EClass然后“创建动态实例”,这将创建一个.xmi文件。
  4. 使用Eclipse打开.xmi文件,这将打开该模型的EMF编辑器。 根据需要进行编辑。
  5. 检查(编辑的).xmi文件的内容。 您将看到格式与Ecore模型完全一致。 您将无法从模型< - > XMI文件更改/自定义映射,因为顾名思义,XMIResourceImpl只读取/保存XMI文件(恰好在XML之上实现)但它不读取/保存任意XML格式。

EMF支持读取/写入XML Schema元模型 (即XSD文件),以便将它们转换为Ecore元模型,但不支持符合此类模式的XML文件(甚至不是Ecore),除非这些文件采用XMI格式。

有关将EMF模型保存到关系数据库中的信息,请参阅: http : //eclipsedriven.blogspot.com/2010/12/persisting-emf-objects-to-rdbms-with.html

我正在使用Teneo。 (以及可选的CDO)

关于“XML”,如果您坚持使用XMI并对其满意,EMF将使您的生活轻松,因为您不需要进行任何映射(与JAXB不同)。 缺点是我们的对象必须是EMF对象。

EMF对象是由EMF生成并实现EObject并直接或间接扩展EObjectImpl的对象。 你通常不想手工编写EMF对象,这将是一件苦差事。 另一方面,JAXB“对象”通常是纯域对象POJO,并且没有JAXB的额外要求。 请注意,与JAXB不同, EMF对象不是POJO。 这解释了EMF和JAXB之间的另一个不同目标。 他们的重叠比你想象的要少。

从XMI(而不是XML)读取非常简单:

XMIResource resource = new XMIResourceImpl(URI.create("file:/path/to/mymodel.xmi")); resource.load(null); System.out.println( resource.eContents().get(0) ); 

您可以使用EMF读取任意XML文件,只要您拥有XSD,并且您甚至不必从XSD生成Java类。
几个月前我在博客上写了这篇文章,但我也会在这里粘贴代码片段。 有关更详细的说明,请参阅我的博客文章, 了解如何使用EMF加载和比较任意XML文件 。

首先,您需要加载XSD并初始化以下几项:

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

之后,您可以像往常一样加载XML文件:

 ResourceSet resourceSet = ResourceSetFactory.createResourceSet(); Resource resource = resourceSet.getResource(xmlURI, true); resource.load(Collections.EMPTY_MAP); EObject root = resource.getContents().get(0); 

我构建了一个小程序,使用emftriple(以前的emf4sw)进行一些基本的模型格式转换,即Ecore XMI(XML文件)到RDF TTL。

我在这里的答案中使用了一些提示,谢谢你们!

也许源代码可以激发你的灵感: https : //github.com/frostyandy2k/model-transformer

执行此类操作的常规方法是从XML模式开始,然后使用它生成EMF模型,然后生成Java代码。 这在EMF教程中有描述。

您不需要实现读/写方法。 而是使用EMF库代码来执行XML导入和导出。 我现在没有把EMF书的副本放在我面前,但它在那里有所涉及。 或者,查看生成的EMF编辑器在加载或保存模型实例时所执行的操作。

编辑

这是我几年前开发的基于EMF的项目的资源实用程序类 。 看看load*方法。 请注意,这不一定是执行此操作的最佳方式……但它对我有用。

编辑2

我刚刚意识到我使用的是XMI而不是纯XML。 使用自定义架构和(可能)自定义架构映射配置XML阅读器可能会有所不同。 那么,回到我原来的答案, 看看生成的代码!!

EMF不是为读取任意XML文件而设计的。 EMF使用XML作为后端。 您的XML文件来自哪个/它们符合哪个模式? 如果您有架构,那么您可以使用它来创建EMF模型,而EMF模型又可以读取您的XML文件。

否则你将不得不对一个确实会序列化到你的XML的EMF模型进行反向工程,这样你就可以读取它,但那将是一个黑客攻击。

UPDATE2之后

我想下一个问题是“加载文件时有什么问题”。 你是怎么做到的,什么是无效的? 或者你不知道怎么做?

首先必须为资源集配置工厂(要使用的文件集的内存中表示),然后使用getResource(URI,bool)加载文件。 我正在做的一些UML的例子:

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

这应该都包含在您已经链接到的教程中。 然后,您可以使用生成的Java API从“root”开始工作。

虽然我对ORM的东西没有经验,但也许你应该看一下CDO 。