在使用与Jena的SPARQL查询时,我试图以更易读的格式获取数据,但是我不知道如何以正确的方式提取数据。 至于现在,输出是:
“http://www.w3.org/TR/2003/PR-owl-guide-20031209/wine#SaucelitoCanyon”
反而希望将“SaucelitoCanyon”作为输出。
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();
}
}
答案 0 :(得分:5)
由于您已经在SPARQL查询中获得了前缀,因此您可以使用 strafter 和 str 函数将URI转换为字符串并在后面取后缀。字首。在下文中,我使用values ?winery { ... }
将?winery
绑定到特定的URI,但您的查询已经处理了这个问题。重要的部分是 bind 之后负责字符串处理。
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"
也就是说,在结构良好的本体中,个人通常会有一个 rdfs:label ,它应该为个人提供字符串标签。当它可用时,您可以考虑简单地检索该值。例如,
SELECT ?winery ?name
WHERE {
#-- ...
?winery rdfs:label ?name
}
之前已在my answer到retrieving the class name of a specific subclass in owl中对此进行了描述,但该问题并未涉及Jena,因此即使基于SPARQL的解决方案相同,也不会重复。
答案 1 :(得分:4)
请注意,在Jena中,您有两个很好的Java源代码来实现良好的qName转换:Prologue
和PrefixMapping
。您的Model
是PrefixMapping
,Query
(如果您编译的话)是Prologue
。这两个对象都有#shortForm(String uri)
方法,您可以使用它来获取缩写形式的URI而无需修改查询。
如果您的模型中定义了前缀,则可以使用PrefixMapping#shortForm(String)
,如下所示(伪代码):
final Model m = // TODO
final String shortForm = m.shortForm(winery.asResource().getURI());
如果您使用Query
编译QueryFactory
,那么您可以在Prologue#shortForm(String)
中使用查询特定的前缀,如下所示(伪代码):
final Query q = QueryFactory.create(/* TODO */);
final String shortForm = q.shortForm(winery.asResource().getURI());
然后值得知道,这将为您提供wine:SaucelitoCanyon
形式的名称(如果定义了wine:
前缀,否则它将为您提供http://www.w3.org/TR/2003/PR-owl-guide-20031209/wine#SaucelitoCanyon
)。您仍然需要拆分结果字符串以获取本地名称,这可能有点冗长:
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);
}
这可以保证您使用与模型或查询中的某些前缀关联的本地名称。
答案 2 :(得分:3)
您可以使用耶拿的"getLocalName" function。这将获得资源的本地名称,这是您似乎正在寻找的:
QuerySolution row = results.next();
RDFNode winery = row.get("winery");
String r = winery.asNode().getLocalName();
System.out.println(r);
或者,您可以直接将节点作为资源获取,这样可以节省一行代码:
String r = row.getResource("winery").getLocalName();
编辑:如下面的评论中所述,此答案仅在您的前缀&#34; wine&#34;就像你在代码中声明它一样。否则结果可能不是所希望的。