首先,请注意,union of 域和范围的语义可能不是您所期望的。在 OWL 中,当你说类 D 是属性 P 的域时,这意味着只要你有一个断言 P(x,y),你就可以推断出 D(x)。这意味着如果 P 的域是联合 C ⊔ D,那么从P(x,y),可以推断出x是C的一个元素⊔ D;即,x 是 C 或 D,但您不一定知道哪个。例如,您可以定义:
hasWings rdfs:domain (Airplane ⊔ Bird)
然后,根据 hasWings(x,2),您可以推断出 x 是飞机还是鸟,但您仍然不知道是哪一个。
无论如何,如果你仍然想要一个联合类作为一个域,你可以这样做。在 OWL 本体映射的 RDF 序列化中,联合的类在一个 RDF 列表中。查询这些有点复杂,但你当然可以做到。由于您没有提供完整的 OWL 本体,我们无法查询您的实际数据(将来,请提供我们可以使用的完整、最小工作数据),但我们可以创建一个简单的本体。有两个类,A 和 B,以及两个属性,p 和 q。 p的域是A,q的域是A或B:
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://example.org/"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#">
<owl:Ontology rdf:about="http://example.org/"/>
<owl:Class rdf:about="http://example.org/#A"/>
<owl:Class rdf:about="http://example.org/#B"/>
<owl:ObjectProperty rdf:about="http://example.org/#q">
<rdfs:domain>
<owl:Class>
<owl:unionOf rdf:parseType="Collection">
<owl:Class rdf:about="http://example.org/#A"/>
<owl:Class rdf:about="http://example.org/#B"/>
</owl:unionOf>
</owl:Class>
</rdfs:domain>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:about="http://example.org/#p">
<rdfs:domain rdf:resource="http://example.org/#A"/>
</owl:ObjectProperty>
</rdf:RDF>
SPARQL 语法更类似于 RDF 的 N3/Turtle 序列化,因此查看该序列化也很有帮助。 unionOf 列表在这里更清晰:
@prefix : <http://example.org/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
<http://example.org/#A>
a owl:Class .
<http://example.org/#p>
a owl:ObjectProperty ;
rdfs:domain <http://example.org/#A> .
<http://example.org/#B>
a owl:Class .
<http://example.org/#q>
a owl:ObjectProperty ;
rdfs:domain [ a owl:Class ;
owl:unionOf ( <http://example.org/#A> <http://example.org/#B> )
] .
: a owl:Ontology .
现在您可以使用这样的查询来查找属性及其域,或者如果其中一个域是联合类,则可以找到联合类:
prefix : <http://example.org/>
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix owl: <http://www.w3.org/2002/07/owl#>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?p ?d where {
?p rdfs:domain/(owl:unionOf/rdf:rest*/rdf:first)* ?d
filter isIri(?d)
}
-----------------------------------------------------
| p | d |
=====================================================
| <http://example.org/#q> | <http://example.org/#A> |
| <http://example.org/#q> | <http://example.org/#B> |
| <http://example.org/#p> | <http://example.org/#A> |
-----------------------------------------------------
该查询的有趣部分是:
?p rdfs:domain/(owl:unionOf/rdf:rest*/rdf:first)* ?d
这表示您遵循从 ?p 到 ?d 的路径,以及路径:
- 以 rdfs:domain 开头
- 后跟零次或多次重复:
- 猫头鹰:unionOf
- 后跟零个或多个 rdf:rest
- 后跟一个 rdf:first
这与这个问题并不完全相关,但您可能会发现在this answer(披露:我的回答)到Is it possible to get the position of an element in an RDF Collection in SPARQL? 中查询 RDF 列表的讨论很有用。
然后,我也加了
filter isIri(?d)
因为否则我们会得到代表联合类的节点,但这是一个您(可能)不想要的空白节点。