如何匹配CIM / RDF中的JAXB元素?

尝试根据IEC 61970(通用信息模型,电力系统模型)从CIM / XML文件加载模型,我发现了一个问题; 根据JAXB,元素之间的图形由@XmlREF @XmlID提供,这两者应该等于匹配。 但是在CIM / RDF中,通过ID引用资源,即rdf:resource =“#_ 37C0E103000D40CD812C47572C31C0AD”包含“#”字符,因此当在rdf中JAXB无法匹配“GeographicalRegion”与“SubGeographicalRegion.Region” :资源属性存在“#”字符。

这是一个例子:

 GeoRegion OpenCIM3bus   SubRegion SubRegion   

我意识到你要求使用JAXB的解决方案,但我会建议你考虑一个基于RDF的解决方案,因为它更灵活,更健壮。 你基本上是在尝试重新构建已经内置的RDF解析器.RDF / XML是一种难以解析的格式,试图破解你自己的解析没有多大意义 – 特别是因为具有非常不同的XML结构的文件可以表达完全相同的信息:只有在查看RDF的级别时才会显而易见。 您可能会发现您的JAXB解析器解决方法适用于一个CIM / RDF文件,但在另一个CIM / RDF文件上完全失败。

所以,这是一个如何使用Sesame RDF API处理文件的示例。 不涉及推理,这只是解析文件并将其放入内存中的RDF模型,然后您可以从任何角度进行操作和查询。

假设您的CIM文件的根元素看起来像这样:

  

(当然只是猜测,但我需要前缀作为正确的例子)

然后你可以使用Sesame的Rio RDF / XML解析器执行以下操作:

  String baseURI = "http://example.org/my/file"; FileInputStream in = new FileInputStream("/path/to/my/cim.rdf"); Model model = Rio.parse(in, baseURI, RDFFormat.RDFXML); 

这将创建文档的内存中RDF模型。 然后,您可以简单地对其进行过滤查询。 例如,要打印出具有_37C0E103000D40CD812C47572C31C0AD作为其SubGeographicalRegion.Region的所有资源的属性:

  String CIM_NS = "http://example.org/cim/"; ValueFactory vf = ValueFactoryImpl.getInstance(); URI subRegion = vf.createURI(CIM_NS, "SubGeographicalRegion.Region"); URI res = vf.createURI("http://example.org/my/file#_37C0E103000D40CD812C47572C31C0AD"); Set subs = model.filter(null, subRegion, res).subjects(); for (Resource sub: subs) { System.out.println("resource: " + sub + " has the following properties: "); for (URI prop: model.filter(sub, null, null).predicates()) { System.out.println(prop + ": " + model.filter(sub, prop, null).objectValue()); } } 

当然,此时您还可以选择将模型转换为其他语法格式,以便您的应用程序进一步处理 – 您认为合适。 关键是RDF / XML解析器已为您解决了带有#和without的标识符之间的差异。

这当然只是个人意见,因为我不知道你的用例的细节,但我认为你会发现这是非常快速和灵活的。 我还应该指出,虽然上述解决方案将整个模型保留在内存中,但如果您发现文件太大,您可以轻松地将其调整为更流式(因此内存密集程度更低)的方法。