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
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.