使用owlready2执行SPARQL查询时出现MinusBlock类型未知错误的解决方法
解决Owlready2中SPARQL MINUS语句报错问题
问题情况
在Google Drive的Quran Corpus文件夹中存储了本体文件quran_data_full.owl,该本体的SPARQL查询在Apache Jena Fuseki上能正常运行并返回正确结果,但将相同查询复制到Google Colab的owlready2代码中时,触发了与MinusBlock相关的ValueError。
原代码
from owlready2 import * onto_path.append("/gdrive/MyDrive/Quran Corpus") go = get_ontology("/gdrive/MyDrive/Quran Corpus/quran_data_full.owl").load() obo = get_namespace("/gdrive/MyDrive/Quran Corpus/") d = list(default_world.sparql(""" PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX owl: <http://www.w3.org/2002/07/owl#> PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> PREFIX qur: <http://quranontology.com/Resource/> SELECT ?verse ?text WHERE {?verse rdf:type qur:Verse. ?verse qur:DiscussTopic ?topic. ?verse rdfs:label ?text. ?topic qur:TopicCompleteName ?topicName. FILTER (REGEX(STR(?topicName), "زكاة" ,"i")). FILTER langMatches(lang(?text),"ar") MINUS { ?verse rdfs:label ?text. FILTER (REGEX(STR(?text), "زكاة" ,"i")).} } """))
报错信息
ValueError: Unknown block type '<MinusBlock [(VAR:'?verse', IRI:'http://www.w3.org/2000/01/rdf-schema#label', VAR:'?text'), <owlready2.sparql.parser.Filter object at 0x7f8b5a75b970>]>'!
报错原因
Owlready2的内置SPARQL解析器不支持MINUS子句,它仅实现了SPARQL规范的核心子集,和Jena Fuseki这种完整支持SPARQL标准的引擎存在功能差异。
解决方案
将MINUS子句替换为FILTER NOT EXISTS,二者在当前查询场景下功能完全等价,且Owlready2支持FILTER NOT EXISTS语法。
修改后的代码
from owlready2 import * onto_path.append("/gdrive/MyDrive/Quran Corpus") go = get_ontology("/gdrive/MyDrive/Quran Corpus/quran_data_full.owl").load() obo = get_namespace("/gdrive/MyDrive/Quran Corpus/") d = list(default_world.sparql(""" PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX owl: <http://www.w3.org/2002/07/owl#> PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> PREFIX qur: <http://quranontology.com/Resource/> SELECT ?verse ?text WHERE { ?verse rdf:type qur:Verse. ?verse qur:DiscussTopic ?topic. ?verse rdfs:label ?text. ?topic qur:TopicCompleteName ?topicName. FILTER (REGEX(STR(?topicName), "زكاة" ,"i")). FILTER langMatches(lang(?text),"ar") FILTER NOT EXISTS { ?verse rdfs:label ?text. FILTER (REGEX(STR(?text), "زكاة" ,"i")). } } """))
内容的提问来源于stack exchange,提问作者Reem
相关产品推荐
相关产品推荐

