EMF = Eclipse Modeling Framework
我必须在我的一个班级项目中使用EMF。我试图了解如何使用EMF执行以下操作:
我需要使用以下所有内容:EMF(不知道是什么)和JPA(DONE)。
我使用过JAXB,我知道,这可以使用JAXB完成,但是(EMF == JAXB)怎么办?!
我使用EMF创建了许多java类,但是它们有很多!我在哪里实现读/写方法以及如何运行EMF项目?
由于
UPDATE1 暗示 http://www.eclipsezone.com/eclipse/forums/t58829.html
UPDATE2
我有架构,我使用.xsd生成了模型代码。现在我在从XML文件中读取数据时遇到了问题。
答案 0 :(得分:14)
您可以使用EMF读取任意XML文件,只要您拥有XSD,并且您甚至不必从XSD生成Java类。
几个月前我在博客上写了这篇文章,但我也会在这里粘贴代码片段。有关详细说明,请参阅How to load and compare arbitrary XML files with EMF上的博文。
首先,您需要加载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);
答案 1 :(得分:4)
EMF使用(默认的,最流行的方式)XMIResourceImpl序列化数据模型,严格使用XMI格式,而不是自定义XML结构。
有关EMF及其用例的文章,请参阅http://eclipsedriven.blogspot.com/。
我同意其他的回答者,EMF可能不是你想要的。
如果我真的想要将EMF用于自定义XML结构(即不是XMI),我可能会使用JAXB来编组/解组我的EMF对象(EObjects)。
因此,EMF与JAXB不同,它们有不同的目的和目标。实际上,您可能会以某种方式组合EMF和JAXB。我从来没有尝试过,但似乎有一些有效的用例。 (正如我上面所说的,用于对EMF对象进行编组/解组)
要了解EMF,您需要切换范例。首先删除“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) );
答案 2 :(得分:1)
执行此类操作的常规方法是从XML模式开始,然后使用它来生成EMF模型,然后生成Java代码。这在this EMF tutorial中描述。
您不需要实现读/写方法。而是使用EMF库代码来执行XML导入和导出。我现在面前没有我的EMF书的副本,但它在那里有所涉及。或者,看一下加载或保存模型实例时生成的EMF编辑器的作用。
编辑
这是我几年前开发的基于EMF项目的resource utility class。查看load*
方法。请注意,这不一定是执行此操作的最佳方式......但它对我有用。
编辑2
我刚刚意识到我使用的是XMI而不是纯XML。使用自定义架构和(可能)自定义架构映射配置XML阅读器可能会有所不同。所以,回到我原来的答案,查看生成的代码!! 。
答案 3 :(得分:0)
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。