启用正向链接后,我将执行以下操作:

"...WHERE { ?class rdf:type rdfs:Class }"


现在,我想不用推理机来做,所以我尝试了:

"...WHERE { ?class rdf:type* rdfs:Class }"


但这给了我类的实例,而不是所有的类。例如,缺少rdfs:Resource。有任何想法吗?如果重要的话,我的本体是here

最佳答案

如果没有理由,您将无法获得100%保证的完整结果。例如,rdfs:Resource经常根本没有在数据集中被显式使用,因此无需推断该类根本就不会出现在数据中。但是对于大多数实际目的,您可以足够接近完整性。

什么时候知道某类资源?有多种可能性:


当它是rdfs:Class类型时;
当它是rdf:type关系的对象时;
当它是rdfs:subClassOf关系的主题或对象时;
当用作rdfs:domainrdfs:range关系的对象时。


那么,如何查询呢?好吧,第一个很简单:

SELECT ?c WHERE { ?c a rdfs:Class }


顺便说一句:在SPARQL中,关键字ardf:type关系的简写。请注意,您不需要传递查询(因此不需要*)。

第二个也很简单:

SELECT ?c WHERE { [] rdf:type ?c }


[]位表示一个匿名变量(因为我们对主题值不感兴趣-此时我们只需要对象)。

第三个有点棘手。我们可以将其分为两部分:首先查询所有属于rdfs:subClassOf关系的资源:

SELECT ?c WHERE { ?c rdfs:subClassOf [] }


然后查询作为关系对象的所有资源:

SELECT ?c WHERE { [] rdfs:subClassOf ?c }


现在,让我们看看是否可以在单个查询中结合这两种模式。我们不能像这样将两个图形模式放在同一个WHERE子句中,因为那样会使它成为逻辑AND(这意味着我们只会取回属于子类关系的主题和对象的资源)。因此,我们需要使用逻辑或。在SPARQL中,可以使用UNION来完成:

SELECT ?c
WHERE {
    { ?c rdfs:subClassOf [] }
    UNION
    { [] rdfs:subClassOf ?c }
}


但是,在这种情况下,我们还可以使用属性路径表达式以不同的方式表示逻辑或,如下所示:

SELECT ?c
WHERE { ?c rdfs:subClassOf|^rdfs:subClassOf [] }


路径表达式p1|p2表示“与这两个关系中的任何一个匹配”。运算符^说“查询关系的倒数”。因此,如果我们将它们放在一起,则上面的路径表达式会说“匹配任何三元组,其中主语是?c且关系是rdfs:subClassOf,或者关系rdfs:subClassOf是倒置的,因此对象与?c ”。

我们可以用类似的方式查询第四个可能性:

SELECT ?c
WHERE { [] rdfs:domain|rdfs:range ?c }


放在一起

SELECT ?c
WHERE {
     { ?c a rdfs:Class }
     UNION
     { [] rdf:type ?c }
     UNION
     { [] rdfs:domain|rdfs:range ?c }
     UNION
     { ?c rdfs:subClassOf|^rdfs:subClassOf [] }
}


这可能可以进一步缩短。当然,如果您很了解本体,就可以进一步简化它(例如,如果您知道自己从不使用域或范围属性,则可以省略该位)。

09-29 22:35