Virtuoso与Jena中SPARQL自动读取命名空间缩写的技术问询
Virtuoso与Jena自动读取服务器端命名空间实现URI缩写
问题背景
我在Virtuoso中配置了以下命名空间:
- @prefix sio: http://semanticscience.org/resource/SIO_ .
- @prefix cheminf: http://semanticscience.org/resource/CHEMINF_ .
- @prefix snomedct: http://purl.bioontology.org/ontology/SNOMEDCT/ .
但使用Jena对Virtuoso执行SPARQL查询时,部分命名空间无法正确缩写。我希望实现SPARQL查询自动读取服务器端配置的命名空间用于URI缩写,而非在本地维护命名空间与缩写的映射,请问Jena与Virtuoso是否支持该功能?
我目前了解一种本地维护映射的实现方式:
- 执行SPARQL查询
- 在本地创建存储命名空间与缩写的映射表
- 用映射表中的缩写替换URI前缀
参考信息
- Virtuoso版本:07.20.3235 (64e6ecd39) Win64单服务器版
测试数据
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . @prefix sio: <http://semanticscience.org/resource/SIO_> . @prefix cheminf: <http://semanticscience.org/resource/CHEMINF_> . @prefix snomedct: <http://purl.bioontology.org/ontology/SNOMEDCT/> . @prefix example: <http://example.org/resource/> . example:7732-18-5 rdf:type snomedct:101782006 . example:7732-18-5 sio:SIO_000008 example:Descriptor_water_boiling_point_15039 . example:Descriptor_water_boiling_point_15039 rdf:type sio:CHEMINF_000257 .
当前Jena代码与SPARQL查询
RDFConnection conn = RDFConnectionRemote.service("http://localhost:8890/sparql").build(); Model model = conn.queryConstruct("CONSTRUCT { ?s ?p ?o . } WHERE { ?s ?p ?o . FILTER ( ?s = <http://example.org/resource/7732-18-5> ) }"); // 输出SPARQL结果 model.write(System.out, "ttl"); // 输出model中的命名空间 Iterator iterator = model.listNameSpaces(); while (iterator.hasNext()) { System.out.println(iterator.next().toString()); }
当前输出结果
SPARQL查询输出
@prefix example: <http://example.org/resource/> . @prefix ns1: <http://semanticscience.org/resource/> . @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . example:7732-18-5 rdf:type <http://purl.bioontology.org/ontology/SNOMEDCT/101782006> ; ns1:SIO_SIO_000008 example:Descriptor_water_boiling_point_15039 .
model.listNameSpaces输出
http://www.w3.org/1999/02/22-rdf-syntax-ns# http://purl.bioontology.org/ontology/SNOMEDCT/101782006 http://semanticscience.org/resource/
解决方案:自动读取Virtuoso命名空间
Virtuoso与Jena支持自动读取服务器端命名空间,实现步骤如下:
1. 查询Virtuoso中的命名空间映射
Virtuoso将配置的命名空间存储在系统图中,可以通过SPARQL查询获取前缀与URI的映射:
SELECT ?prefix ?namespace WHERE { GRAPH <http://www.openlinksw.com/schemas/virtrdf#> { ?ns virtrdf:namespacePrefix ?prefix ; virtrdf:namespaceURI ?namespace . } }
2. 在Jena中加载命名空间到Model
在获取查询结果的Model后,先执行上述命名空间查询,将得到的前缀映射添加到Model中,再进行序列化输出。修改后的代码示例:
RDFConnection conn = RDFConnectionRemote.service("http://localhost:8890/sparql").build(); // 1. 查询Virtuoso中的命名空间映射 ResultSet nsResults = conn.queryResultSet( "SELECT ?prefix ?namespace WHERE { GRAPH <http://www.openlinksw.com/schemas/virtrdf#> { ?ns virtrdf:namespacePrefix ?prefix ; virtrdf:namespaceURI ?namespace . } }" ); // 2. 执行业务查询 Model model = conn.queryConstruct( "CONSTRUCT { ?s ?p ?o . } WHERE { ?s ?p ?o . FILTER ( ?s = <http://example.org/resource/7732-18-5> ) }" ); // 3. 将服务器端的命名空间映射添加到Model while (nsResults.hasNext()) { QuerySolution sol = nsResults.next(); String prefix = sol.getLiteral("prefix").getString(); String namespace = sol.getResource("namespace").getURI(); model.setNsPrefix(prefix, namespace); } // 4. 输出格式化后的结果 model.write(System.out, "ttl");
效果说明
执行修改后的代码,输出结果会自动使用Virtuoso中配置的前缀缩写:
sio:SIO_000008会正确显示,而非ns1:SIO_SIO_000008snomedct:101782006会正确缩写,而非完整URI
补充说明
- 若Virtuoso中配置的命名空间未出现在查询结果中,可检查是否将命名空间设置为全局可用(而非仅特定图)
- Jena的Model默认会自动提取URI的公共前缀,但仅会生成类似
ns1的默认缩写,无法复用服务器端配置的前缀,因此必须主动加载服务器端的命名空间映射才能实现预期效果
内容的提问来源于stack exchange,提问作者chenkun
相关产品推荐
相关产品推荐

