2

Given the following Turtle:

prefix : <http://example.org/>
prefix blank: <http://example.org/blank>
prefix rdf:      <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

:alice    :friends  blank:b1 .
blank:b1  rdf:first "Alice" ;
          rdf:rest  blank:b2  .
blank:b2  rdf:first "Bob"   ;
          rdf:rest  blank:b3   .
blank:b3  rdf:first "Carol" ;
          rdf:rest  rdf:nil .

I would like to create a SPARQL query that translates all URIs like :b1, :b2, ... to blank nodes like: _:b1, _:b2, ...

So the expected result would be:

prefix : <http://example.org/>
prefix rdf:      <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

:alice :friends  _:b1 .
_:b1   rdf:first "Alice" ;
       rdf:rest  _:b2  .
_:b2   rdf:first "Bob"   ;
       rdf:rest  _:b3   .
_:b3   rdf:first "Carol" ;
       rdf:rest  rdf:nil .

which would be the equivalent to:

prefix : <http://example.org/>
prefix blank: <http://example.org/blank>
prefix rdf:      <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

:alice    :friends  ("Alice" "Bob" "Carol" ). 

An initial attempt that I tried is:

prefix ex: <https://example.com/ns#>
prefix rdf:      <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

CONSTRUCT {
  ?bnode1 rdf:first ?value ;
          rdf:rest  ?bnode2 .
  ?s ?p ?o .        
}
where {
  { ?iri1  rdf:first ?value ;
           rdf:rest  ?iri2 . }
  BIND(BNODE(str(?iri1)) as ?bnode1)
  BIND(BNODE(str(?iri2)) as ?bnode2)
}

But the semantics of BNODEaccording to SPARQL spec indicates that it generates a new blank node for each solution mapping, so the generated blank nodes are not linked. For example, using Jena, I obtained:

@prefix :      <http://example.org/> .
@prefix blank: <http://example.org/blank> .
@prefix ex:    <https://example.com/ns#> .
@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .

[ rdf:first  "Carol" ;
  rdf:rest   [] 
] .

[ rdf:first  "Alice" ;
  rdf:rest   [] 
] .

[ rdf:first  "Bob" ;
  rdf:rest   [] 
] .

which is not what I want.

Stanislav Kralin
  • 11,070
  • 4
  • 35
  • 58
Labra
  • 1,412
  • 1
  • 13
  • 33
  • I don't think it's possible as for each new solution mapping independently of the seed a new bnode will be generated - in general, bnodes are still ongoing work I guess, e.g. https://github.com/w3c/sparql-dev/issues/36 – UninformedUser Jul 05 '23 at 14:14
  • Indeed, I also think it may not be possible, but maybe someone has a nice suggestion. A very simple solution is to use `sed`. – Labra Jul 05 '23 at 16:49
  • Why this modelling approach? In this particular case, why not to use RDF containers instead of RDF collections: `:alice :hasFriends [rdf:li "Alice", "Bob", "Carol"]`? Why do you need RDFS vocabulary at all, why not `:alice :hasFriend "Alice", "Bob", "Carol"`? BTW, Jena list functions (`list:member` etc.) work fine with your sample data :). – Stanislav Kralin Jul 07 '23 at 09:54
  • I agree that the modeling the values in that way is not the best way. The context of this question is when one wants to convert the values associated to a property of some subject to a list of values. I proposed a solution [here](https://stackoverflow.com/questions/62030465/sparql-construct-to-generate-rdf-collection-from-group-by-bindings/76617717#76617717) but it would be prettier if the generated list used blank nodes instead of literals. – Labra Jul 08 '23 at 06:46

0 Answers0