Попытка загрузить модель из файла CIM/XML в соответствии с IEC 61970 (общая информационная модель для моделей энергосистем), я нашел проблему; Согласно графикам JAXB между элементами предоставляется @XmlREF @XmlID, и оба они должны быть равны. Но в CIM/RDF ссылки на ресурс через идентификатор, т.е. Rdf: resource = "#_ 37C0E103000D40CD812C47572C31C0AD", содержат символ "#", поэтому JAXB не может сопоставлять "GeographicalRegion" и "SubGeographicalRegion.Region", когда в rdf: атрибут ресурса присутствует символ "#".
Вот пример:
<cim:GeographicalRegion rdf:ID="_37C0E103000D40CD812C47572C31C0AD">
<cim:IdentifiedObject.name>GeoRegion</cim:IdentifiedObject.name>
<cim:IdentifiedObject.localName>OpenCIM3bus</cim:IdentifiedObject.localName>
</cim:GeographicalRegion>
<cim:SubGeographicalRegion rdf:ID="_ID_SubGeographicalRegion">
<cim:IdentifiedObject.name>SubRegion</cim:IdentifiedObject.name>
<cim:IdentifiedObject.localName>SubRegion</cim:IdentifiedObject.localName>
<cim:SubGeographicalRegion.Region rdf:resource="#_37C0E103000D40CD812C47572C31C0AD"/>
</cim:SubGeographicalRegion>
Я понимаю, что вы просите решение с помощью JAXB, но я настоятельно рекомендую вам рассмотреть решение на основе RDF, поскольку оно более гибкое и надежное. Вы в основном пытаетесь изобрести то, что уже создали встроенные партизаны RDF. RDF/XML - сложный формат для синтаксического анализа, не имеет смысла пытаться взломать ваш собственный синтаксический анализ вместе - тем более, что файлы, имеющие очень разные структуры XML может выражать точно такую же информацию: это становится очевидным только при просмотре уровня RDF. Вы можете обнаружить, что ваш обозреватель JAXB работает в одном файле CIM/RDF, но полностью не работает на другом.
Итак, вот пример того, как обрабатывать ваш файл с помощью Sesame RDF API. При этом не выполняется никаких указаний, это просто анализирует файл и помещает его в встроенную RDF-модель, которую вы можете манипулировать и запрашивать под любым углом.
Предполагая, что корневой элемент вашего CIM файла выглядит примерно так:
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:cim="http://example.org/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<Resource> 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.
Это, конечно, личное мнение, потому что я не знаю подробностей вашего прецедента, но я думаю, вы обнаружите, что это довольно быстро и гибко. Следует также отметить, что хотя вышеупомянутое решение сохраняет всю модель в памяти, вы можете легко адаптировать ее к более потоковому (и, следовательно, менее интенсивному в памяти) подходу, если вы обнаружите, что ваши файлы слишком большие.