1

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?

TallTed
  • 9,069
  • 2
  • 22
  • 37
Cola
  • 2,097
  • 4
  • 24
  • 30
  • 2
    `(

    |!

    )*` is the workaround here given that it's not part of the specs. Note, it should be clear that this might work bad in worst case regarding performance given - path queries are not that simple to evaluate without appropriate index etc

    – UninformedUser Nov 14 '18 at 03:55
  • 1
    I forgot to say, indeed you won't be able to reuse the variable bound to all the subproperties of the given property. Still, don't know whether you really need this in your case. I mean, how many subproperties do you have in your dataset? – UninformedUser Nov 14 '18 at 07:59
  • Thanks, turns out i have 3. But the reason i would have liked to use a variable is to capture the dynamic addition of more. – Cola Nov 14 '18 at 18:52

2 Answers2

2

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.

TallTed
  • 9,069
  • 2
  • 22
  • 37
0

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.

RobV
  • 28,022
  • 11
  • 77
  • 119