Seus dados podem ser representados em RDF como
data.n3
:@prefix : <http://example.org/> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
:Network rdfs:subClassOf :Main .
:ATM rdfs:subClassOf :Network .
:ARPANET rdfs:subClassOf :Network .
:Software rdfs:subClassOf :Main .
:Linux rdfs:subClassOf :Software .
:Windows rdfs:subClassOf :Software .
:XP rdfs:subClassOf :Windows .
:Win7 rdfs:subClassOf :Windows .
:Win8 rdfs:subClassOf :Windows .
A partir daqui, você só quer uma consulta SPARQL que encontre todas as coisas conectadas a uma classe específica por um caminho (incluindo o caminho vazio) de
rdfs:subClassOf
propriedades. prefix : <http://example.org/>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?superclass where {
:Win7 rdfs:subClassOf* ?superclass
}
--------------
| superclass |
==============
| :Win7 |
| :Windows |
| :Software |
| :Main |
--------------
Os resultados nessa consulta não são necessariamente ordenados por sua posição no caminho (embora neste caso sejam). Se você precisar deles em ordem, você pode fazer isso (que é baseado em esta resposta sobre o cálculo da posição de elementos em uma lista RDF ):
prefix : <http://example.org/>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?class where {
:Win7 rdfs:subClassOf* ?mid .
?mid rdfs:subClassOf* ?class .
}
group by ?class
order by count(?mid)
Isso encontra cada ancestral
?class
de :Win7
bem como cada ?mid
ancestral intermediário. Para ancestral ?class
, a distância é calculada como o número de relações intermediárias entre (count(?mid)
). Ele ordena os resultados com base nessa distância, então :Win7
é o ancestral mais próximo, :Windows
depois disso, e assim por diante. Você pode até fazer uma formatação sofisticada que deseja assim:
prefix : <http://example.org/>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select (group_concat( ?name ; separator="--" ) as ?path) where {
{
select ?name where {
:Win7 rdfs:subClassOf* ?mid .
?mid rdfs:subClassOf* ?class .
bind( strAfter( str(?class), "http://example.org/") as ?name )
}
group by ?class ?name
order by count(?mid)
}
}
-----------------------------------
| path |
===================================
| "Win7--Windows--Software--Main" |
-----------------------------------
Ele pode ser possível fazer algum processamento de string mais sofisticado e obter a string de várias linhas. Você pode ver a última parte de esta resposta onde há alguma formatação sofisticada para uma matriz de ideias bem alinhada.