如何使用EMF读取XML文件?

时间:2010-03-30 09:09:24

标签: java xml eclipse eclipse-emf

EMF = Eclipse Modeling Framework

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

  1. 阅读XML,
  2. 将值添加到对象中。
  3. 使用ORM将对象中的值保存到数据库。 - 完成
  4. 使用ORM从数据库获取数据并生成XML。
  5. 我需要使用以下所有内容:EMF(不知道是什么)和JPA(DONE)。

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

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

    由于

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

    UPDATE2

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

4 个答案:

答案 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”部分,让它离开你的脑海。然后我建议你做以下事情:

  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格式。
  6. 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