Search code examples
sparqlrdf

Creating a SPARQL query that extracts information out of a `rdf:Bag` without loss of information


I'm pretty new to RDF, but I need to construct an RDF query to extract some information from an existing RDF graph. In essence, I'm trying to purge existing RDF graphs of the rdf:Bag construct.

For instance, given the RDF graph:

@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix bqbiol: <http://biomodels.net/biology-qualifiers/> .

<http://omex-library.org/NewOmex.omex/NewModel.xml#_1>
    bqbiol:is [
        rdf:_1 <http://identifiers.org/uniprot/P00742> ;
        a rdf:Bag
    ] .

I need to extract the information out of the rdf:Bag without loss of information. So in this instance, the resulting rdf graph would be:

@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix bqbiol: <http://biomodels.net/biology-qualifiers/> .

<http://omex-library.org/NewOmex.omex/NewModel.xml#_1>
    bqbiol:is <http://identifiers.org/uniprot/P00742> ;

My alternative is to make this change in using libxml2 before creating the graph in the first place, but it seems like sparql should be useful here (please correct me if I'm wrong).

Can anybody help me with this ? So far, all I have figured out is that a generic "find me everything" sqarql query, aka

SELECT ?x ?y ?z 
WHERE {?x ?y ?z }

produces

x,y,z
_:r1r21532r1, http://www.w3.org/1999/02/22-rdf-syntax-ns#type, http://www.w3.org/1999/02/22-rdf-syntax-ns#Bag
_:r1r21532r1, http://www.w3.org/1999/02/22-rdf-syntax-ns#_1, http://identifiers.org/uniprot/P00742
http://omex-library.org/NewOmex.omex/NewModel.xml#_1, http://biomodels.net/biology-qualifiers/is, _:r1r21532r1

so whatever sparql query I generate will need to involve the specific r1r21532r1 blank node.

Edit: A little bit of progress.

The spaqrl query

SELECT  ?s ?p1 ?p2
WHERE {
    ?s ?p1 [ ?p2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#Bag> ] . 
}

produces

| uri<http://omex-library.org/NewOmex.omex/NewModel.xml#_1> | uri<http://biomodels.net/biology-qualifiers/is> | uri<http://www.w3.org/1999/02/22-rdf-syntax-ns#type> |

Which is closer, but looses some information along the way.


Solution

  • SELECT ?x (bqbiol:is AS ?y) ?z {
        ?x bqbiol:is [ a rdf:Bag ; !a ?z ] . 
    }
    

    or

    SELECT  ?x ?y ?z {
        BIND (bqbiol:is AS ?y)
        ?x ?y [ a rdf:Bag ; !a ?z ] . 
    }
    

    In Apache Jena or under RDFS entailment:

    SELECT ?x (bqbiol:is AS ?y) ?z {
        ?x bqbiol:is [ a rdf:Bag ; rdfs:member ?z ] . 
    }
    

    You could also use the CONSTRUCT query form:

    CONSTRUCT { ?x bqbiol:is ?z } {
        ?x bqbiol:is [ a rdf:Bag ; !a ?z ]
    }