Reputation: 47
Im trying to get the data in a more readable format when using a SPARQL query with Jena, however I have no idea how to extract the data in a proper way. As for now, the output is:
"http://www.w3.org/TR/2003/PR-owl-guide-20031209/wine#SaucelitoCanyon"
Where instead would like to just have the "SaucelitoCanyon" as a output.
public JenaQuery() {
String wineRegion = "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n"
+ "PREFIX owl: <http://www.w3.org/2002/07/owl#>\n"
+ "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>\n"
+ "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n"
+ "PREFIX wine:<http://www.w3.org/TR/2003/PR-owl-guide-20031209/wine#>\n"
+ "SELECT ?region ?winery \n"
+ "WHERE {?wine wine:locatedIn ?region . \n"
+ "?region wine:locatedIn wine:CaliforniaRegion . \n"
+ "?wine wine:hasMaker ?winery}";
String inputFileName = "wine.rdf";
// create an empty model
Model model = ModelFactory.createDefaultModel();
// use the FileManager to find the input file
InputStream in;
in = FileManager.get().open(inputFileName);
if (in == null) {
throw new IllegalArgumentException(
"File: " + inputFileName + " not found");
}
// read the RDF/XML file
model.read(in, null);
try (QueryExecution qexec = QueryExecutionFactory.create(wineRegion, model)) {
ResultSet results = qexec.execSelect();
while (results.hasNext()) {
QuerySolution row = results.next();
RDFNode winery = row.get("winery");
System.out.println(winery);
}
qexec.close();
}
}
Upvotes: 2
Views: 976
Reputation: 959
You can use the "getLocalName" function in Jena. That will get you the local name of the resource, which is what you seem to be looking for:
QuerySolution row = results.next();
RDFNode winery = row.get("winery");
String r = winery.asNode().getLocalName();
System.out.println(r);
Alternatively you can get the node as a resource directly, which saves you one line of code:
String r = row.getResource("winery").getLocalName();
Edit: as stated in the comments below, this answer will only be valid if your prefix "wine" is as you have declared it in your code. Otherwise the results may not be as desired.
Upvotes: 3
Reputation: 2823
Note that in Jena you have two nice Java sources for nice qName conversions: Prologue
and PrefixMapping
. Your Model
is a PrefixMapping
and your Query
(if you compiled it) is a Prologue
. Both of these objects have a #shortForm(String uri)
method that you can use to get a shortened form of a URI without modifying your query.
If your model has prefixes defined in it, you can use PrefixMapping#shortForm(String)
as follows (pseudocode):
final Model m = // TODO
final String shortForm = m.shortForm(winery.asResource().getURI());
If you compile your Query
using QueryFactory
, then you can use query-specific prefixes in Prologue#shortForm(String)
as follows (pseudocode):
final Query q = QueryFactory.create(/* TODO */);
final String shortForm = q.shortForm(winery.asResource().getURI());
It's then worth knowing that this will give you a name of the form wine:SaucelitoCanyon
(if the wine:
prefix is defined, otherwise it will give you http://www.w3.org/TR/2003/PR-owl-guide-20031209/wine#SaucelitoCanyon
). You would still need to split the resulting string to get just the local name which may be a little verbose:
final String longName = winery.asResource().getURI();
final String localName;
if( !shortForm.equals(longName) ) {
localName = shortForm.split(":")[1];
}
else {
throw new IllegalStateException("could not resolve prefix for "+longName);
}
This provides you a guarantee that you are using the local name associated with some prefix in your model or your query.
Upvotes: 5
Reputation: 85813
Since you've already got the prefix in the SPARQL query, you can use the strafter and str functions to convert the URIs to strings and take the suffix after the prefix. In the following, I've used values ?winery { ... }
to bind ?winery
to a particular URI, but your query already takes care of that. The important part is the bind afterward that takes care of the string processing.
PREFIX wine: <http://www.w3.org/TR/2003/PR-owl-guide-20031209/wine#>
SELECT ?winery ?localname
WHERE {
values ?winery { wine:SomeWinery }
bind( strafter(str(?winery),str(wine:)) as ?localname )
}
winery localname
<http://www.w3.org/TR/2003/PR-owl-guide-20031209/wine#SomeWinery> "SomeWinery"
That said, in well structured ontologies, individuals will often have an rdfs:label that should provide a string label for an individual. When it's available, you might consider simply retrieving that value. E.g.,
SELECT ?winery ?name
WHERE {
#-- ...
?winery rdfs:label ?name
}
This was previously described in my answer to retrieving the class name of a specific subclass in owl, but that question didn't involve Jena, so it's not quite a duplicate, even though the same SPARQL-based solution works.
Upvotes: 5