Search code examples
sparqlconstruct

Sparql query to construct a new graph


I have two graphs with similar data but a slight difference.

my goal is to merge them using SPARQL and perform the integration. I want a final output of two RDF graphs that has a slight difference in a single RDF graph using SPARQL.

example one graph is :

ns0:BaseRoleClassLib
  a ns0:ExternalReference ;
  ns0:externalReferenceAlias "BaseRoleClassLib" .

ns0:maxTransportationWeight
  a ns0:Attribute ;
  schema:name "maxTransportationWeight" ;
  ns0:hasValue "35" .

second graph is :

ns0:BaseRoleClassLib
  a ns0:ExternalReference ;
ns0:maxTransportationWeight
  a ns0:Attribute ;
  schema:name "maxTransportationWeight" ;
  ns0:hasValue "35.0" .

The only difference is one has the transport value in integer and other in the float.

So I write a query to generalise them :

select distinct ?integer
from <graph1>
from <graph2>
where {
?s ns0:hasValue ?y
Bind(xsd:integer(xsd:decimal(?y)) as ?integer)
}
}

This converts the difference in to generalised form of integer. Now my next goal is I want to integrate these files into a single RDF by using the above result .

I want an RDF file which has the union of these and the solved generalization of float to integer.

S1 , S2 -> generalization -> integration -> s3 RDF

How can I achieve this using SPARQL constructor / insert ?

Thanks so much


Solution

  • This can be done pretty straightforwardly by CONSTRUCT. SPARQL update doesn't seem to support FROM, so you'd need to use a UNION of GRAPH statements. The following should get the merge you are looking for - basically filter out the old ns0:hasValue value and insert the new one:

    CONSTRUCT { 
       ?s ?p ?o .
       ?s ns0:hasValue ?intValue .
    }
    FROM <graph1>
    FROM <graph2>
    WHERE {
       ?s ?p ?o .
       OPTIONAL{?s ns0:hasValue ?origValue .}
       BIND(IF(datatype(?origValue) = xsd:integer, ?origValue, xsd:integer(STRBEFORE(str(?origValue), ".")) )as ?intValue)
       FILTER (?p != ns0:hasValue)
    }
    

    Note that conversion of float to integer isn't straightforward. You's have to live with rounding down or have logic to round by decimal values.