Redland R中RDF三元组对象类型定义及非字面量写入异常排查
问题分析与解决方案
首先,你的核心问题是混淆了Redland R包中URI节点和空白节点的创建逻辑,同时对Statement构造函数的参数用法理解有误:
错误原因拆解
- 当你执行
addStatement(model, new("Statement",world, "a:Sian","b:likes","a:John",objectType="blank"))时,objectType="blank"会告诉Redland把传入的"a:John"当作空白节点的本地标识,而非URI。所以Redland生成了_:a:John(空白节点),而非你预期的<a:John>(URI节点)。 - 你的SPARQL查询期望
?x是<a:John>这个URI节点,但实际存储的是完全不同的空白节点_:a:John,自然无法匹配查询条件。
另外,你的第一个三元组代码也有潜在问题:"a:Jane"被解析为带引号的字面量"a:Jane",而非URI节点<a:Jane>,这可能也不符合你的真实需求。
正确实现步骤
下面是修正后的代码,分两种场景说明:
场景1:宾语是URI节点(你的真实需求)
如果你想存储<a:Sian> <b:likes> <a:John>,不需要设置objectType,而是要确保宾语被识别为URI节点:
library(Redland) # 初始化world和内存模型 world <- new("World") model <- new("Model", world, storage = new("Storage", world, "memory")) # 推荐方式:显式创建URI对象,避免歧义 subj_john <- new("URI", world, "a:John") pred_likes <- new("URI", world, "b:likes") obj_jane <- new("URI", world, "a:Jane") addStatement(model, new("Statement", world, subj_john, pred_likes, obj_jane)) subj_sian <- new("URI", world, "a:Sian") obj_john <- new("URI", world, "a:John") addStatement(model, new("Statement", world, subj_sian, pred_likes, obj_john)) # 简化方式:通过objectType指定为uri(显式创建更清晰,优先推荐上面的方式) # addStatement(model, new("Statement", world, "a:John", "b:likes", "a:Jane", objectType="uri")) # addStatement(model, new("Statement", world, "a:Sian", "b:likes", "a:John", objectType="uri"))
场景2:宾语确实是空白节点(如果需要的话)
如果你真的需要存储空白节点(比如_:john),应该显式创建BlankNode对象,而非通过字符串加objectType:
# 创建空白节点,指定本地标识 blank_john <- new("BlankNode", world, id = "john") # 添加三元组:<a:Sian> <b:likes> _:john addStatement(model, new("Statement", world, subj_sian, pred_likes, blank_john))
验证SPARQL查询
现在运行你的查询,就能得到预期结果了:
query_str <- 'select ?a ?b where {?a <b:likes> ?x. ?x <b:likes> ?b.}' query <- new("Query", world, query_str) result <- executeQuery(model, query) # 遍历查询结果 while(nextResult(result)) { cat(sprintf("?a: %s, ?b: %s\n", getResultValue(result, "a"), getResultValue(result, "b"))) } # 释放资源 freeQuery(result)
预期输出:
?a: a:Sian, ?b: a:Jane
内容的提问来源于stack exchange,提问作者drw
相关产品推荐
相关产品推荐

