问题
I like to delete a RDF tuple from a RDF file using dotNetRDF. Here is the code I'm using
public void deleteDest(string destID)
{
TripleStore store = new TripleStore();
Graph rdf = new Graph();
FileLoader.Load(rdf, rdfFilePath, new RdfXmlParser());
store.Add(rdf);
SparqlUpdateParser parser = new SparqlUpdateParser();
SparqlParameterizedString cmdString = new SparqlParameterizedString();
cmdString.CommandText = "PREFIX j.0: <http://www.example.org/destDetails#>"
+ "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>"
+ "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>"
+ "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>"
+ "DELETE "
+ "WHERE { "
+ " ?dest j.0:ID \"" + destID + "\" "
+ "}";
SparqlUpdateCommandSet cmds = parser.ParseFromString(cmdString);
LeviathanUpdateProcessor processor = new LeviathanUpdateProcessor(store);
processor.ProcessCommandSet(cmds);
rdf.SaveToFile(rdfFilePath);
}
Here is the structure of my RDF file
<rdf:RDF xml:base="http://www.example.org/destDetails#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:xsd="http://www.w3.org/2001/XMLSchema#" xmlns:ns0="http://www.example.org/destDetails#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about="&ns0;0165a659-54ea-4e80-bee7-9d3951d47ae3">
<ns0:ID>0165a659-54ea-4e80-bee7-9d3951d47ae3</ns0:ID>
<ns0:destination rdf:resource="&ns0;VELES" />
<ns0:distrName>Test Test</ns0:distrName>
<ns0:hasTimeStart>17:00</ns0:hasTimeStart>
<ns0:hasTimeStop>17:55</ns0:hasTimeStop>
<ns0:moneyOneDir>130 den.</ns0:moneyOneDir>
<ns0:moneyTwoDir>---</ns0:moneyTwoDir>
</rdf:Description>
</rdf:RDF>
However, no changes are applied to the RDF file.
回答1:
The problem is that your update operates over the default graph but that your dataset only contains a named graph.
FileLoader.Load(rdf, rdfFilePath, new RdfXmlParser());
store.Add(rdf);
When you do the above this loads data into your graph and assigns that graph a name based on the source of the data - in your case it gets a file://
URI. Then when you add it to the store the store uses the current name of the graph (from the BaseUri
property of the graph) and adds it as a named graph.
However your DELETE
only references the default graph which is empty in your example and your named graph is not modified in any way. There are several different ways to fix this problem.
1 - Construct your dataset explicitly
You can specify that your named graph be treated as the default graph like so:
// Create a dataset and use the named graph as the default graph
InMemoryDataset ds = new InMemoryDataset(store, rdf.BaseUri);
// Use the dataset to create the processor
LeviathanUpdateProcessor processor = new LeviathanUpdateProcessor(ds);
2 - Add your named graph as the default graph
You can make your named graph be treated as the default graph by removing its name before you add it to the store:
FileLoader.Load(rdf, rdfFilePath, new RdfXmlParser());
rdf.BaseUri = null; // Remove the name from the graph
// If the graph has no name it is added as the default graph
store.Add(rdf);
3 - Rewrite your update
You can rewrite your DELETE
to reference the named graph explicitly:
cmdString.CommandText = @"PREFIX j.0: <http://www.example.org/destDetails#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
DELETE WHERE
{
GRAPH @graph { ?dest j.0:ID @destID }
}";
cmdString.SetUri("graph", rdf.BaseUri);
cmdString.SetLiteral("destID", destID);
Note that I've used verbatim string literals for readability and injected the parameters via SetUri()
and SetLiteral()
rather than string concatenation.
回答2:
There is an extra space \"" + destID + "\" "
(marked with an X --> \"" + destID + "\"X")
来源:https://stackoverflow.com/questions/18173387/sparql-delete-query-dotnetrdf-does-not-modify-rdf-file