这听起来很简单,但我还没有找到一个很好的解决方案。我希望在我的本体中找到只有一个子类的类。
到目前为止,我的处理方式如下:
SELECT (COUNT(?anything) AS ?count) ?class
WHERE {
GRAPH <> {
?class rdf:type owl:Class.
?class rdfs:subClassOf ?anything.
?anything rdf:type owl:Class.
} group by ?class
然后理论上我应该能够按计数排序,并且值为 1 的结果应该只有 1 个子类。但是,当我执行此查询时,计数与我期望的完全不符,例如我的测试用例应该返回 1,它确实如此,但是另一个根本没有子类的类也返回 1。和一个具有 3 个子类的类返回计数为 4。
你正在寻找的 SPARQL 查询类似于
SELECT ?class WHERE {
?sub rdfs:subClassOf ?class
}
GROUP BY ?class
HAVING (COUNT(DISTINCT ?sub) = 1)
但是,正如 UninformedUser 在评论中提到的那样,如果有可用的 OWL 推理,则可能会有很多你可能意想不到的答案,例如
owl:Nothing rdfs:subClassOf ex:YourClass
和
ex:YourClass rdfs:subClassOf ex:YourClass
如果这些阻止查询产生你正在寻找的结果,你应该添加一个过滤器,如
SELECT ?class WHERE {
?sub rdfs:subClassOf ?class
FILTER ( ?sub != ?class && ?sub != owl:Nothing )
}
GROUP BY ?class
HAVING (COUNT(DISTINCT ?sub) = 1)
谢谢你俩!这帮助很大。我现在已经学会了“拥有”。我也不知道一个类可以是它自己的子类,所以过滤器很有帮助。
也许更能说明问题和让我沮丧的是,真正的问题是我在 WHERE 语句中的声明,如果我翻转了这个语句: ?class rdfs:subClassOf ?anything。在我的情况下,我已经得到了正确的答案,但很高兴知道这可能并不总是正确的,因此过滤器。
@robin 是的,当所有具有类型 X 的东西也具有类型 Y 时,类 X 是 Y 的子类。因此,每个类都是其自身的子类。通常我们不会直接断言,但 OWL 推理器会识别它。