Java 正在加载没有指定名称空间的XML作为EMF模型:";带有uri的包';空';“未找到”例外情况
我有一个XSD文件,我将其转换为ecore模型,并从中生成模型代码。现在,我想为该模式加载一个xml文件,但不断出现错误:Java 正在加载没有指定名称空间的XML作为EMF模型:";带有uri的包';空';“未找到”例外情况,java,eclipse-emf,Java,Eclipse Emf,我有一个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,
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);
publicstaticvoidmain(字符串[]args)引发IOException{
minimapackage.eINSTANCE.eClass();
MinimalPackageInstance=MinimalPackage.eINSTANCE;
Resource.Factory.Registry reg=Resource.Factory.Registry.INSTANCE;
Map m=reg.getExtensionFactoryMap();
m、 put(“*”,新的XMLResourceFactoryImpl());
//获取新的资源集
ResourceSet RESET=新的ResourceSetImpl();
setResourceFactoryRegistry(reg);
reset.getPackageRegistry().put(minimapackage.eNS_URI,
(e.eINSTANCE);
reset.getPackageRegistry().put(null,
(e.eINSTANCE);
//获取资源
URI=URI
.createFileURI(“C:/Users/mboeschen/safety/devel/eclipse\u插件…”。。。
/load/examples/minimal.xml“;
Resource=reset.getResource(uri,true);
RootType r=(RootType)resource.getContents().get(0);
系统输出println(r);
架构文件如下所示:
BasicExtendedMetaData bemd = new BasicExtendedMetaData() {
private static final String NAMESPACE_GOOGLE_EXT_2_2 = "http://www.google.com/kml/ext/2.2";
private static final String NAMESPACE_OPENGIS_2_2 = "http://www.opengis.net/kml/2.2";
private static final String NAMESPACE_DEFAULT = NAMESPACE_OPENGIS_2_2;
@Override
public EPackage getPackage(String namespace) {
if(namespace==null) {
namespace = NAMESPACE_DEFAULT;
}
return super.getPackage(namespace);
}
@Override
public EStructuralFeature getElement(String namespace, String name) {
// try to find feature in OPENGIS package
EStructuralFeature result = super.getElement(NAMESPACE_OPENGIS_2_2, name);
if (feature == null) {
// if not found, try GOOGLE_EXT
feature = super.getElement(NAMESPACE_GOOGLE_EXT_2_2, name);
}
return feature;
}
});
这是xml文件:
你知道这里发生了什么吗?非常感谢你的帮助!当你生成模型时,你可能得到了一个生成的[YourModelName]ResourceFactoryImpl类。我的KML编辑器也遇到了同样的问题,我就是这样解决的:
public class OgckmlResourceFactoryImpl extends ResourceFactoryImpl {
...
/**
* Creates an instance of the resource.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
@Override
public Resource createResource(URI uri) {
XMLResource result = new OgckmlResourceImpl(uri);
setupOptions(result);
return result;
}
protected void setupOptions(XMLResource result)
{
...
result.getDefaultLoadOptions().put(XMLResource.OPTION_EXTENDED_META_DATA, new BasicExtendedMetaData()
{
private static final String NAMESPACE_GOOGLE_EXT_2_2 = "http://www.google.com/kml/ext/2.2";
private static final String NAMESPACE_OPENGIS_2_2 = "http://www.opengis.net/kml/2.2";
private static final String NAMESPACE_DEFAULT = NAMESPACE_OPENGIS_2_2;
@Override
public EPackage getPackage(String namespace) {
if(namespace==null){
namespace = NAMESPACE_DEFAULT;
}
return super.getPackage(namespace);
}
@Override
public EStructuralFeature getElement(String namespace, String name)
{
if (feature == null)
feature = super.getElement(NAMESPACE_OPENGIS_2_2, name);
if (feature == null)
feature = super.getElement(NAMESPACE_GOOGLE_EXT_2_2, name);
return feature;
}
});
...
}
}
公共类OgckmlResourceFactoryImpl扩展了ResourceFactoryImpl{
...
/**
*创建资源的实例。
*
*
*@不生成
*/
@凌驾
公共资源createResource(URI){
XMLResource结果=新的OgckmlResourceImpl(uri);
设置选项(结果);
返回结果;
}
受保护的无效设置选项(XMLResource结果)
{
...
result.getDefaultLoadOptions().put(XMLResource.OPTION_EXTENDED_META_DATA,新的BasicExtendedMetaData()
{
私有静态最终字符串名称空间\u GOOGLE\u EXT\u 2\u 2=”http://www.google.com/kml/ext/2.2";
私有静态最终字符串名称空间_OPENGIS_2_2=”http://www.opengis.net/kml/2.2";
私有静态最终字符串NAMESPACE_DEFAULT=NAMESPACE_OPENGIS_2_2;
@凌驾
公共EPackage getPackage(字符串命名空间){
if(命名空间==null){
名称空间=名称空间\默认值;
}
返回super.getPackage(名称空间);
}
@凌驾
public EsstructuralFeature getElement(字符串命名空间、字符串名称)
{
如果(功能==null)
feature=super.getElement(名称空间\u OPENGIS\u 2\u 2,名称);
如果(功能==null)
feature=super.getElement(名称空间\谷歌\外部\ 2 \名称);
返回特性;
}
});
...
}
}
我在ATL透视图上也有同样的问题,我所做的是为了避免“PackageNotFoundException”的问题:首先你不应该让你的模型名称空间为空,识别URI的名称空间“nsURI”将有助于在代码生成器中识别Ecore模型“xml文件。因此,只要命名nsURI,任何名称都会与我们的EPackage匹配。此外,我重写了xsi:schemeLocation=“…”manulay,也许这没有什么意义,但最终它解决了问题。在过去两年中,我改进了@Severin为我的项目提出的解决方案。因此,我给出了以下补充答案:
通过XMLResource
加载资源时,会调用多个帮助器类来解析XML并将其映射到EMF/Ecore。可以通过更改加载选项来替换这些类中的大多数。可以在多个位置执行此操作:
具有默认加载选项ResourceSet
默认加载选项(通常通过生成的Resource
设置)ResourceFactory
方法可以提供加载选项Resource.load()
Resource
和XMLResource
中的常量定义
对于最初描述的问题,有两个关键点特别重要:
提供了一个处理程序,如果EMF找不到合适的EPackage,将调用该处理程序XMLResource.OPTION\u MISSING\u PACKAGE\u HANDLER
生成一个布尔值(指示是否使用扩展元数据,通常为XMLResource.OPTION\u EXTENDED\u META\u DATA
),或一个true
的具体实例,该实例提供XML和Ecore之间的各种映射信息ExtendedMetaData
- 只涉及一个名称空间和一个EPackage
- 资源的内容类型是明确的(即,您/知道/资源包含与您的EPackage匹配的内容)
MissingPackageHandler
实现,如下所示:
MissingPackageHandler mph = new MissingPackageHandler() {
@Override
public EPackage getPackage(final String nsURI) {
return MyModelEPackage.eINSTANCE;
}
};
至少在我的项目中,我还需要设置这个ExtendedMetaData
:
BasicExtendedMetaData bemd = new BasicExtendedMetaData(new EPackageRegistryImpl(EPackage.Registry.INSTANCE)) {
@Override
protected boolean isFeatureNamespaceMatchingLax() {
return true;
}
};
如果超过一个EPa