How to use a kleene star operator (*) or it's variant (+) with variables in sparql?

288 views Asked by At

I have some working code for getting all the ancestors of a term in a hierarchy. Following:

    PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
    PREFIX skos-xl: <http://www.w3.org/2008/05/skos-xl#>
    PREFIX rdf: <http://www.w3.org/2000/01/rdf-schema#>

    select  ?grandparentliteralform (count(?parent) as ?distance)
    { ?iri skos:broader+ ?parent .
     ?parent skos:broader* ?grandparent .
     ?grandparent skos-xl:prefLabel ?grandparentlabel .
     ?grandparentlabel skos-xl:literalForm ?grandparentliteralform .
    } 
    group by ?grandparent
    order by DESC(?distance)

It breaks when an IRI's broader predicate is a subproperty (?p rdf:subPropertyOf skos:broader) So right now I am doing this to capture all the subproperty predicates:

select  ?grandparentliteralform (count(?parent) as ?distance)
{ ?iri ?p ?parent .
 ?parent skos:broader* ?grandparent .
 ?grandparent skos-xl:prefLabel ?grandparentlabel .
 ?grandparentlabel skos-xl:literalForm ?grandparentliteralform .
 ?p rdf:subPropertyOf   skos:broader .
} 
group by ?grandparent
order by DESC(?distance)

What i would really like to do is :

select  ?grandparentliteralform (count(?parent) as ?distance)
{ ?iri ?p+ ?parent .
 ?parent ?p* ?grandparent .
 ?grandparent skos-xl:prefLabel ?grandparentlabel .
 ?grandparentlabel skos-xl:literalForm ?grandparentliteralform .
 ?p rdf:subPropertyOf   skos:broader .
} 
group by ?grandparent
order by DESC(?distance)

but using ?p+ or ?p* throws an error.

Unexpected token syntax error, unexpected <variable>, expecting <decimal literal> or <double literal> or <integer literal>

How can I use */+ with variables?

2

There are 2 answers

0
TallTed On BEST ANSWER

You can't. As the Property Paths section of the SPARQL 1.1 spec states:

The ends of the path may be RDF terms or variables. Variables can not be used as part of the path itself, only the ends.

0
RobV On

You could potentially use alternatives to capture this:

?parent (skos:broader|your:alternative)* ?grandparent

Exact form will need to reflect your data structure and whether you want to allow mixes of skos:broader and your alternative (which my example allows). You can move the * operator inside the brackets and add it to each alternative if you want pure chains of specific properties.