我有一个XSD文件,我将其转换为生态模型,并从中生成模型代码。现在我想为该架构加载一个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>
这里有什么想法吗?任何帮助表示赞赏!
答案 0 :(得分:3)
在过去的两年里,我已经完善了@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
实施:
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;
}
};
如果涉及多个EPackage
和名称空间,则MissingPackageHandler
可能过于高级,需要通过ExtendedMetaData
实现直接进行区分。
根据@Severin的回答,可以这样做:
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;
}
});
答案 1 :(得分:0)
我在ATL透视图上遇到同样的问题,我做了什么来避免“PackageNotFoundException”的问题:拳头你不应该让你的模型名称空间为NULL,识别URI的名称空间“nsURI “将有助于识别代码生成器中的Ecore模型”xml文件。所以只需命名nsURI,任何名称都匹配你的 EPackage 。另外我重写xsi:schemeLocation =“....”manulay,也许这没有意义,但最后它解决了问题