问题描述
我正在尝试使用RDFlib更新以空白节点为对象的三元组的对象。我首先在第一个函数中选择空白节点,然后将此空白节点插入第二个函数的更新查询中,但是,这并没有为我提供所需的输出。我无法使用add()方法或initBindings,因为我需要保存为用户执行的SPARQL查询。
样本数据
@prefix rr: <http://www.w3.org/ns/r2rml#> .
[ rr:objectMap [ rr:column "age" ;
rr:language "dhhdhd"] ].
mapping_graph = Graph().parse("valid_mapping.ttl",format="ttl")
# find the blank node for the update query
def find_om_IRI():
query = """SELECT ?om
WHERE {
?om rr:language 'dhhdhd' .
}
"""
qres = mapping_graph.query(query)
for row in qres:
return row[0]
# insert blank node as subject to update query
def change_language_tag():
om_IRI = find_om_IRI()
update_query = """
PREFIX rr: <http://www.w3.org/ns/r2rml#>
DELETE DATA{
_:%s rr:language 'dhhdhd' .
}
""" % (om_IRI)
processUpdate(mapping_graph,update_query)
print(update_query)
print(mapping_graph.serialize(format="ttl").decode("utf-8"))
return update_query
change_language_tag()
这将返回以下输出。保持图形不变。
@prefix rr: <http://www.w3.org/ns/r2rml#> .
[ rr:objectMap [ rr:column "age" ;
rr:language "dhhdhd"] ].
解决方法
如果基于空白节点值进行过滤。这是我提出的最后一个查询。
PREFIX rr: <http://www.w3.org/ns/r2rml#>
DELETE { ?om rr:language "dhhdhd" }
INSERT { ?om rr:language "en-fhfhfh" }
WHERE {
SELECT ?om
WHERE {
?om rr:language "dhhdhd" .
FILTER(str(?om) = "ub1bL24C24").
}
}
,
的确如此,正如评论者@TallTed所说的那样:``不能在单独的查询中直接引用空白节点''。您正在尝试使用未明确为其定义BN的事情,即保留其绝对身份,例如跨不同的查询。您应该采用相对识别的方法(参考已识别的URI,节点来定位BN)或单个SPARQL查询。因此,这个问题是RDF / SPARQL问题,而不是RDFlib问题。
您说:“我无法合并查询,因为可能存在其他具有相同语言标记的对象映射”。因此,如果由于缺乏唯一性而无法确定地引用节点,则必须更改数据,但是我怀疑您可以-请在最后查看建议。
然后您说:“我已经找到了解决方案,并相应地更新了问题。它确实是个hack……”是的,不要这样做!您应该有一个不依赖于RDFlib怪癖的解决方案!一般而言,RDF和语义Web都是关于通用定义的标准数据和查询的,因此不要依赖特定的工具包来处理这样的数据问题。仅将RDFlib用作实现,而应使用另一种语言复制。我个人首先将所有RDFlib三重添加/删除/选择代码建模为标准SPARQL查询,以便我的RDFlib代码只是与标准功能等效的代码。
在您自己的答案中,您说过“如果您根据空白节点值进行过滤...”,也不要这样做!
我的建议是更改您的基础数据,以包括事物的表示形式(命名节点等),您可以将其用于查询。如果您无法在不依靠黑客的情况下区分要更改的事物,那么您将遇到需要解决的数据建模问题。我确实认为您可以区分对象图。
在数据中,您必须能够固定要更改其语言的特定对象图。对象映射表的每一列是否唯一,并且列的rr:column
值是否唯一标识?如果是这样:
SELECT ?lang
WHERE {
?om rr:column ?col . ?om rr:language ?lang .
FILTER (?col = "age")
}
这将为您获取“年龄”列的对象映射,以便对其进行更改:
DELETE {
?om rr:language ?lang .
}
INSERT {
?om rr:language "new-language" .
}
WHERE {
?om rr:column ?col . ?om rr:language ?lang .
FILTER (?col = "age")
}