在 SPARQL CONSTRUCT 查询中作为主题的文字

Literal as subject in SPARQL CONSTRUCT query

我正在努力创建一个正确的 SPARQL 查询,它将生成正确的格式,以便我可以在其中打开 Protege。我们的 ontology 是关于鸡尾酒的,我们希望在我们的数据库中包含所有 DBPedia 鸡尾酒,包括成分 (dbp:ingredients) 和配方 (dbp:prep)。在数据库中获取鸡尾酒效果很好,但配料和配方却不行。我现在有以下查询:

CONSTRUCT {?drink dct:subject ?category.
?drink dbp:prep ?recipe.
?drink dbp:ingredients ?ingredients.
?drink rdf:type owl:NamedIndividual .
?category rdf:type owl:Class.
dct:subject rdf:type owl:ObjectProperty.
dbp:prep rdf:type owl:ObjectProperty.
dbp:ingredient rdf:type owl:Objectproperty.
}
WHERE {
?drink dct:subject ?category.
?drink dbp:prep ?recipe.
?drink dbp:ingredients ?ingredients.}

由于现在没有声明 ?ingredients 和 ?recipe,所以它不会显示在 Protege 的个人选项卡中。但是当我将其添加到查询的 CONSTRUCT 部分时:

?recipe rdf:type owl:NamedIndividual.
?ingredients rdf:type owl:NamedIndividual.

我收到一个错误:

Virtuoso RDF01 Error Bad variable value in CONSTRUCT: "*5 cL vodka *10 cL orange juice" (tag 246 box flags 0) is not a valid subject, only object of a triple can be a literal

我想是因为 dbpedia 上的 prep 和 ingredients 只是一个字符串,没有链接数据。 但是,我如何才能让它在 Protege 中显示出来?

不可能将文字作为 RDF 三元组的主题。相反,为食谱和配料创建资源 + 将字符串值附加为 rdfs:comment(或者可能是 rdfs:label)可能是一种解决方法。它是这样工作的:

CONSTRUCT {
?drink dct:subject ?category.
?drink dbp:prep ?recipe.
?drink dbp:ingredients ?ingredients.
?drink rdf:type owl:NamedIndividual .
?category rdf:type owl:Class.
dct:subject rdf:type owl:ObjectProperty.
dbp:prep rdf:type owl:ObjectProperty.
dbp:ingredients rdf:type owl:Objectproperty.
# add string values as rdfs:comment
?recipe rdfs:comment ?recipe_str .
?ingredients rdfs:comment ?ingredients_str
}
WHERE {
?drink dct:subject ?category.
?drink dbp:prep ?recipe_str.
?drink dbp:ingredients ?ingredients_str.
BIND(URI(CONCAT("http://dbpedia.org/resource/recipe", MD5(STR(?recipe_str)))) as ?recipe)
BIND(URI(CONCAT("http://dbpedia.org/resource/ingredients", MD5(STR(?ingredients_str)))) as ?ingredients)
}

请注意,如果食谱(resp. ingredients)已经是一个资源,它将以某种方式失败。它不适用于 DBpedia 上的 dbp:prepdbp:ingredients,但一般来说,如果您不确定并且您有一些 rdf:Property 实际上允许资源和文字,您需要妥善处理,例如通过使用 IF-ELSE 构造:

BIND(IF(isLiteral(?recipe_str), URI(CONCAT("http://dbpedia.org/resource/recipe", MD5(STR(?recipe_str)))), ?recipe_str) as ?recipe)
BIND(IF(isLiteral(?ingredients_str), URI(CONCAT("http://dbpedia.org/resource/ingredients", MD5(STR(?ingredients_str)))), ?ingredients_str)  as ?ingredients)

而且您还必须省略 rdfs:comment 三元组,然后确实...