假设我们有一个OWL文件,其中包含以下属性以及域和范围:
Domain Property Range
----------------------------
tour hascountry country
country hascity city
city hasward ward
ward hashouse house
使用SPARQL,我怎样才能得到结果""旅游和众议院课程?也就是说,其域名和范围的属性是"路径"从巡回到领域,从范围到众议院。只有这两个类,我们怎样才能找到如下结果?似乎某种循环可能是必要的,但我不知道如何在SPARQL中做到这一点。
|tour -------- (hascountry) ----- country|
|country -------- (hascity) ----- city |
|city -------- (hasward) ----- ward |
|ward -------- (hashouse) ----- house |
答案 0 :(得分:1)
首先,使用一些真实数据总是更容易。我们无法针对我们没有的数据编写真正的SPARQL查询。将来,请务必提供一些我们可以使用的样本。目前,这里有一些示例数据描述了您提到的属性的域和范围。另请注意,属性不会连接类;属性连接个人。属性可以包含域和范围,这为我们提供了一种推断有关属性相关个人的其他信息的方法。无论如何,这是数据:
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix : <https://stackoverflow.com/q/29737549/1281433/> .
:hascountry rdfs:domain :tour ; rdfs:range :country .
:hascity rdfs:domain :country ; rdfs:range :city .
:hasward rdfs:domain :city ; rdfs:range :ward .
:hashouse rdfs:domain :ward ; rdfs:range :house .
现在,请注意,如果您按照rdfs:domain属性向后到:hascountry,则可以从:tour to:country:然后按照rdfs:range属性 forward to:country。在SPARQL中,您可以将其写为属性路径:
:tour ^rdfs:domain/rdfs:range :country
如果您可以关注该属性路径的链,则可以找到&#34;之间的所有属性。 :游览和:房子:
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix : <https://stackoverflow.com/q/29737549/1281433/>
select ?domain ?property ?range where {
#-- find ?properties that have a domain
#-- and range...
?property rdfs:domain ?domain ;
rdfs:range ?range .
#-- where there's a ^rdfs:domain to rdfs:range
#-- chain from :tour to ?domain...
:tour (^rdfs:domain/rdfs:range)* ?domain .
#-- and from ?range to :house.
?range (^rdfs:domain/rdfs:range)* :house .
}
-------------------------------------
| domain | property | range |
=====================================
| :ward | :hashouse | :house |
| :city | :hasward | :ward |
| :country | :hascity | :city |
| :tour | :hascountry | :country |
-------------------------------------
如果你想要属性&#34;按顺序&#34;从开始类到结束类,您可以计算从起始类到每个属性的距离和顺序。您可以使用my answer到Is it possible to get the position of an element in an RDF Collection in SPARQL?中的技术来完成此操作。这是SPARQL查询的样子:
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix : <https://stackoverflow.com/q/29737549/1281433/>
select ?domain ?property ?range
(count(?mid) as ?dist)
where {
#-- find ?properties that have a domain
#-- and range...
?property rdfs:domain ?domain ;
rdfs:range ?range .
#-- where there's a ^rdfs:domain to rdfs:range
#-- chain from :tour to ?domain...
:tour (^rdfs:domain/rdfs:range)* ?domain .
#-- and from ?range to :house.
?range (^rdfs:domain/rdfs:range)* :house .
#-- then, compute the "distance" from :tour
#-- to the property. This is based on binding
#-- ?mid to each class in between them and
#-- taking the number of distinct ?mid values
#-- as the distance.
:tour (^rdfs:domain/rdfs:range)* ?mid .
?mid (^rdfs:domain/rdfs:range)* ?domain .
}
group by ?domain ?property ?range
order by ?dist
--------------------------------------------
| domain | property | range | dist |
============================================
| :tour | :hascountry | :country | 1 |
| :country | :hascity | :city | 2 |
| :city | :hasward | :ward | 3 |
| :ward | :hashouse | :house | 4 |
--------------------------------------------
我在选择中包含了?dist,因此我们可以看到值。您不必选择它以便按它排序。你也可以这样做:
select ?domain ?property ?range {
#-- ...
}
group by ?domain ?property ?range
order by count(?mid)
-------------------------------------
| domain | property | range |
=====================================
| :tour | :hascountry | :country |
| :country | :hascity | :city |
| :city | :hasward | :ward |
| :ward | :hashouse | :house |
-------------------------------------