java加载XML时没有指定名称空间作为EMF模型:“uri为'null'的包未找到”异常
我有一个XSD文件,我将其转换为ecore模型,并从中生成模型代码。现在,我想为该模式加载一个xml文件,但不断出现错误:
org.eclipse.emf.ecore.xmi.PackageNotFoundException:
Package with uri 'null' not found.
(file:/C:/Users/mboeschen/safety/devel/eclipse_plugins...
/de.offis.etas.load/examples/minimal.xml, 2, 7)
由于这是直接在我的xml文件中的根标记之后,我怀疑在读取根标记后出现了问题
我的代码如下:
public static void main(String[] args) throws IOException {
MinimalPackage.eINSTANCE.eClass();
MinimalPackage packageInstance = MinimalPackage.eINSTANCE;
Resource.Factory.Registry reg = Resource.Factory.Registry.INSTANCE;
Map<String, Object> m = reg.getExtensionToFactoryMap();
m.put("*", new XMLResourceFactoryImpl());
// Obtain a new resource set
ResourceSet resSet = new ResourceSetImpl();
resSet.setResourceFactoryRegistry(reg);
resSet.getPackageRegistry().put(MinimalPackage.eNS_URI,
MinimalPackage.eINSTANCE);
resSet.getPackageRegistry().put(null,
MinimalPackage.eINSTANCE);
// Get the resource
URI uri = URI
.createFileURI("C:/Users/mboeschen/safety/devel/eclipse_plugins...
/de.offis.etas.load/examples/minimal.xml");
Resource resource = resSet.getResource(uri, true);
RootType r = (RootType) resource.getContents().get(0);
System.out.println(r);
架构文件如下所示:
<?xml version="1.0" encoding="US-ASCII"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" >
<xs:element name="Root">
<xs:complexType>
<xs:sequence>
<xs:element name="Inner" type="MyType">
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="MyType">
<xs:sequence> </xs:sequence>
</xs:complexType>
</xs:schema>
这是xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<Root>
<Inner>
</Inner>
</Root>
知道这里发生了什么吗?感谢您的帮助
# 1 楼答案
在过去两年中,我改进了@Severin为我的项目提出的解决方案。因此,我补充回答如下:
当通过
XMLResource
加载资源时,会调用几个助手类来解析XML并将其映射到EMF/Ecore。这些类中的大多数可以通过更改加载选项来替换。有几个地方可以做到这一点:ResourceSet
有默认的加载选项Resource
默认加载选项(通常通过生成的ResourceFactory
设置)Resource.load()
方法提供加载选项根据您拥有的访问权限(您自己生成的代码与第三方生成的代码)以及加载资源的位置/频率,您需要使用这些选项之一来添加到加载选项中
加载选项以键值映射的形式出现。例如,键由
Resource
和XMLResource
中的常数定义对于最初描述的问题,有两个关键点特别重要:
XMLResource.OPTION_MISSING_PACKAGE_HANDLER
提供了一个处理程序,如果EMF找不到合适的EPackage,就会调用它XMLResource.OPTION_EXTENDED_META_DATA
要么产生一个布尔值(指示是否使用扩展元数据,通常是true
),要么产生一个ExtendedMetaData
的具体实例,它提供XML和Ecore之间的各种映射信息李>对于简单的情况,当
您可以给出一个
MissingPackageHandler
实现,如下所示:至少在我的项目中,我还需要设置这个^{:
如果涉及多个
EPackage
和名称空间,那么MissingPackageHandler
可能级别太高,需要由ExtendedMetaData
实现直接进行区分按照@Severin的回答,可以这样做:
# 2 楼答案
我在ATL透视图上也有同样的问题,我是如何避免出现“PackageNotFoundException”问题的:首先,你不应该让你的模型名称空间为空,标识URI的名称空间“nsURI”将有助于标识代码生成器xml文件中的Ecore模型。因此,只要命名nsURI,任何名称都将匹配urEPackage。此外,我还重写了xsi:schemeLocation=“…”曼努雷,也许这没有道理,但最终它解决了问题
# 3 楼答案
生成模型时,可能会生成一个[YourModelName]ResourceFactoryImpl类。我的KML编辑器也遇到了同样的问题,我就是这样解决的: