Search code examples
sparqlrdfsemantic-websemanticsblank-nodes

How to recursively expand blank nodes in SPARQL construct query?


There is probably an easy to answer to this, but I can't even figure out how to formulate the Google query to find it.

I'm writing SPARQL construct queries against a dataset that includes blank nodes. So if I do a query like

CONSTRUCT {?x ?y ?z .} WHERE {?x ?y ?z .}

Then one of my results might be:

nm:John nm:owns _:Node

Which is a problem if all of the

_:Node nm:has nm:Hats

triples don't also get into the query result somehow (because some parsers I'm using like rdflib for Python really don't like dangling bnodes).

Is there a way to write my original CONSTRUCT query to recursively add all triples attached to any bnode results such that no bnodes are left dangling in my new graph?


Solution

  • Recursion isn't possible. The closest I can think of is SPARQL 1.1 property paths (note: that version is out of date) but bnode tests aren't available (afaik).

    You could just remove the statements with trailing bnodes:

    CONSTRUCT {?x ?y ?z .} WHERE 
    {
      ?x ?y ?z .
      FILTER (!isBlank(?z))
    }
    

    or try your luck fetching the next bit:

    CONSTRUCT {?x ?y ?z . ?z ?w ?v } WHERE 
    {
      ?x ?y ?z .
      OPTIONAL {
        ?z ?w ?v
        FILTER (isBlank(?z) && !isBlank(?v))
      }
    }
    

    (that last query is pretty punishing, btw)

    You may be better off with DESCRIBE, which will often skip bnodes.