如何使用 EMF 读取 XML 文件?
Posted
技术标签:
【中文标题】如何使用 EMF 读取 XML 文件?【英文标题】:How to use EMF to read XML file? 【发布时间】:2011-02-02 09:25:42 【问题描述】:EMF = Eclipse 建模框架
我必须在我的一个课堂项目中使用 EMF。我正在尝试了解如何使用 EMF 执行以下操作:
-
读取 XML,
将值放入对象中。
使用 ORM 将对象中的值保存到数据库。 - 完成
使用 ORM 从数据库中获取数据并生成 XML。
我需要使用:EMF(不知道怎么做)和 JPA(完成)来完成所有这些工作。
我使用过 JAXB,我知道,这可以使用 JAXB 来完成,但是 (EMF == JAXB) 怎么样?!
我已经使用 EMF 创建了许多 java 类,但是它们太多了!我在哪里实现读/写方法以及如何运行 EMF 项目?
谢谢
更新1 暗示 http://www.eclipsezone.com/eclipse/forums/t58829.html
UPDATE2
我有架构,并且使用 .xsd 生成了模型代码。现在我在从 XML 文件中读取数据时遇到问题。
【问题讨论】:
我不认为 EMF 是为此目的而设计的。这是一个建模,而不是一个绑定框架 它用于XML Binding,我很确定。 @Bozho - EMF 是(或可以用作)建模框架或绑定框架。这取决于你从哪里开始......以及你的观点。 (这是元建模经常被误解的一个方面。模型可以被视为数据,反之亦然。) @Stephen C 谢谢,很高兴知道。 【参考方案1】:您可以使用 EMF 读取任意 XML 文件,前提是您拥有它们的 XSD,并且您甚至不必从 XSD 生成 Java 类。 几个月前我在博客上写过这个,但我也会在这里粘贴代码 sn-ps。有关更详细的解释,请参阅我在 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);
【讨论】:
嗨@Zsolt Török - 我在什么包中找到ResourceSetFactory
?【参考方案2】:
EMF 使用(默认、最流行的方式)XMIResourceImpl 序列化数据模型,它严格使用 XMI 格式,而不是自定义 XML 结构。
有关 EMF 及其用例的文章,请参阅 http://eclipsedriven.blogspot.com/。
我同意其他回答者的观点,即 EMF 可能不是您想要的。
如果我真的想使用带有自定义 XML 结构(即不是 XMI)的 EMF,我可能会使用 JAXB 来编组/解组我的 EMF 对象(EObjects)。
因此 EMF 与 JAXB 不同,它们有不同的目的和目标。事实上,您可能可以通过某种方式将 EMF 和 JAXB 结合起来。我从未尝试过,但似乎有有效的用例。 (正如我上面所说,用于将 EMF 对象编组/解组到 XML)
要了解 EMF,您需要转换您的范式。首先删除“XML”部分,让它从你的脑海中消失。那我建议你做以下事情:
-
创建一个空的 EMF 项目。
创建一个简单的 Ecore 文件 (.ecore),或从 Internet 获取。或者从任何 XML Schema/UML 文件导入 Ecore 模型。
右键单击一个 EClass 然后“创建动态实例”,这将创建一个 .xmi 文件。
使用 Eclipse 打开 .xmi 文件,这将打开该模型的 EMF 编辑器。根据需要进行编辑。
检查(编辑的).xmi 文件的内容。您会看到该格式完全符合 Ecore 模型。您将无法更改/自定义模型 XMI 文件的映射,因为顾名思义,XMIResourceImpl 仅读取/保存 XMI 文件(恰好在 XML 之上实现)但它不读取/保存任意 XML 格式。
EMF 支持读取/写入 XML 模式元模型(即 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) );
【讨论】:
【参考方案3】:我构建了一个小程序,它使用 emftriple(以前的 emf4sw)进行一些基本的模型格式转换,即 Ecore XMI(XML 文件)到 RDF TTL。
我在这里使用了答案中的一些提示,所以谢谢你们!
也许源代码可以启发你:https://github.com/frostyandy2k/model-transformer
【讨论】:
【参考方案4】:做这种事情的正常方法是从一个 XML 模式开始,然后用它来生成 EMF 模型,然后生成 Java 代码。这在this EMF tutorial 中有描述。
您不需要实现读/写方法。而是使用 EMF 库代码来执行 XML 导入和导出。我现在没有我面前的 EMF 书,但它在里面。或者,查看生成的 EMF 编辑器在您加载或保存模型实例时的作用。
编辑
这是我几年前开发的一个基于 EMF 的项目的resource utility class。查看load*
方法。请注意,这不一定是最好的方法......但它对我有用。
编辑 2
我刚刚意识到我使用的是 XMI 而不是纯 XML。使用自定义模式和(可能)自定义模式映射配置 XML 阅读器可能会有所不同。所以,回到我原来的答案,看看生成的代码!!。
【讨论】:
你能给我一个开始,什么是EMF库,它有读/写xml文件的方法?【参考方案5】:EMF 不是为读取任意 XML 文件而设计的。 EMF 使用 XML 作为后端。您的 XML 文件来自哪里/它们符合哪个模式?如果你有这个模式,那么你可以用它来创建一个 EMF 模型,然后希望它能够读取你的 XML 文件。
否则您将不得不对一个确实会序列化为您的 XML 的 EMF 模型进行逆向工程,以便您能够阅读它,但那将是一个 hack。
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。
【讨论】:
是的,在希望将 EMF 模型存储在数据库中时,CDO 或 Teneo 值得研究。特尼奥:eclipse.org/modeling/emft/?project=teneo以上是关于如何使用 EMF 读取 XML 文件?的主要内容,如果未能解决你的问题,请参考以下文章