遍历耶拿的 anonymous/blank 个节点
Traversing anonymous/blank nodes in Jena
我正在使用 Apache Jena 的 API,其中由于 unionOf 和 intersectionOf,图表也包含一些 anonymous/blank 节点。这样的例子之一是:
<owl:Class>
<owl:unionOf rdf:parseType="Collection">
<rdf:Description rdf:about="http://www.summyUrl.com/something#Entity1"/>
<rdf:Description rdf:about="http://www.summyUrl.com/something#Entity2"/>
</owl:unionOf>
</owl:Class>
这是一个匿名 node/resource。当我尝试获取它的 URI 时,它类似于:
"-50a5734d:15d839467d9:-1b8b"
我既无法使用此类 URI 执行 SPARQL 查询(由于解析此类 URI 时出现异常),也无法找到合适的 Jena 方法来处理它。
我正在寻找一种方法来分解这些节点并获取它的所有嵌套资源。
例如在下面的例子中,它应该 return <http:/.../Entity1>
, <http:/.../Entity2>
和 <http:/.../Entity3>
<owl:Class>
<owl:unionOf rdf:parseType="Collection">
<rdf:Description rdf:about="http://www.summyUrl.com/something#Entity1"/>
<owl:unionOf rdf:parseType="Collection">
<rdf:Description rdf:about="http://www.summyUrl.com/something#Entity2"/>
<rdf:Description rdf:about="http://www.summyUrl.com/something#Entity3"/>
</owl:unionOf>
</owl:unionOf>
</owl:Class>
有没有Jena内置的方法来处理它?
如果没有,我怎样才能高效地做到?
使用 jena-model-api:
String s = "<rdf:RDF\n" +
" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n" +
" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n" +
" xmlns:owl=\"http://www.w3.org/2002/07/owl#\"\n" +
" xmlns:rdfs=\"http://www.w3.org/2000/01/rdf-schema#\"\n" +
" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema#\">\n" +
" <owl:Ontology/>\n" +
" <owl:Class>\n" +
" <owl:unionOf rdf:parseType=\"Collection\">\n" +
" <owl:Class rdf:about=\"http://www.summyUrl.com/something#Entity1\"/>\n" +
" <owl:Class>\n" +
" <owl:unionOf rdf:parseType=\"Collection\">\n" +
" <owl:Class rdf:about=\"http://www.summyUrl.com/something#Entity1\"/>\n" +
" <owl:Class rdf:about=\"http://www.summyUrl.com/something#Entity2\"/>\n" +
" </owl:unionOf>\n" +
" </owl:Class>\n" +
" </owl:unionOf>\n" +
" </owl:Class>\n" +
"</rdf:RDF>";
Model m = ModelFactory.createDefaultModel();
try (InputStream in = new ByteArrayInputStream(s.getBytes(StandardCharsets.UTF_8))) {
m.read(in, Lang.RDFXML.getLabel());
}
//m.write(System.out, "ttl");
m.listStatements()
.mapWith(Statement::getObject)
.filterKeep(RDFNode::isURIResource)
.mapWith(RDFNode::asResource)
.filterDrop(OWL.Class::equals)
.filterDrop(OWL.Ontology::equals)
.filterDrop(RDF.nil::equals)
.mapWith(Resource::getURI)
.forEachRemaining(System.out::println);
输出:
http://www.summyUrl.com/something#Entity1
http://www.summyUrl.com/something#Entity2
http://www.summyUrl.com/something#Entity1
这只是一个例子。有很多方法可以处理任何事情
我试过这样做,效果很好:
/**
* Explodes <b>Anonymous resource</b> (Collection resource) in recursive way and provides
* nested resources. Mainly considers <code>owl:unionOf</code>, <code>owl:intersactionOf</code>, <code>rdf:first</code> and <code>rdf:rest</code>
* while traversing.
*
* @param resource
* @return LinkedList<Resource>
*/
private List<Resource> explodeAnonymousResource(Resource resource)
{
private static List<Property> collectionProperties = new LinkedList<Property>(Arrays.asList(OWL.unionOf,OWL.intersectionOf,RDF.first,RDF.rest));
List<Resource> resources=new LinkedList<Resource>();
Boolean needToTraverseNext=false;
if(resource.isAnon())
{
for(Property cp:collectionProperties)
{
if(resource.hasProperty(cp) && !resource.getPropertyResourceValue(cp).equals(RDF.nil))
{
Resource nextResource=resource.getPropertyResourceValue(cp);
resources.addAll(explodeAnonymousResource(nextResource));
needToTraverseNext=true;
}
}
if(!needToTraverseNext)
{
resources.add(resource);
}
}
else
{
resources.add(resource);
}
return resources;
}
我正在使用 Apache Jena 的 API,其中由于 unionOf 和 intersectionOf,图表也包含一些 anonymous/blank 节点。这样的例子之一是:
<owl:Class>
<owl:unionOf rdf:parseType="Collection">
<rdf:Description rdf:about="http://www.summyUrl.com/something#Entity1"/>
<rdf:Description rdf:about="http://www.summyUrl.com/something#Entity2"/>
</owl:unionOf>
</owl:Class>
这是一个匿名 node/resource。当我尝试获取它的 URI 时,它类似于:
"-50a5734d:15d839467d9:-1b8b"
我既无法使用此类 URI 执行 SPARQL 查询(由于解析此类 URI 时出现异常),也无法找到合适的 Jena 方法来处理它。
我正在寻找一种方法来分解这些节点并获取它的所有嵌套资源。
例如在下面的例子中,它应该 return <http:/.../Entity1>
, <http:/.../Entity2>
和 <http:/.../Entity3>
<owl:Class>
<owl:unionOf rdf:parseType="Collection">
<rdf:Description rdf:about="http://www.summyUrl.com/something#Entity1"/>
<owl:unionOf rdf:parseType="Collection">
<rdf:Description rdf:about="http://www.summyUrl.com/something#Entity2"/>
<rdf:Description rdf:about="http://www.summyUrl.com/something#Entity3"/>
</owl:unionOf>
</owl:unionOf>
</owl:Class>
有没有Jena内置的方法来处理它?
如果没有,我怎样才能高效地做到?
使用 jena-model-api:
String s = "<rdf:RDF\n" +
" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n" +
" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n" +
" xmlns:owl=\"http://www.w3.org/2002/07/owl#\"\n" +
" xmlns:rdfs=\"http://www.w3.org/2000/01/rdf-schema#\"\n" +
" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema#\">\n" +
" <owl:Ontology/>\n" +
" <owl:Class>\n" +
" <owl:unionOf rdf:parseType=\"Collection\">\n" +
" <owl:Class rdf:about=\"http://www.summyUrl.com/something#Entity1\"/>\n" +
" <owl:Class>\n" +
" <owl:unionOf rdf:parseType=\"Collection\">\n" +
" <owl:Class rdf:about=\"http://www.summyUrl.com/something#Entity1\"/>\n" +
" <owl:Class rdf:about=\"http://www.summyUrl.com/something#Entity2\"/>\n" +
" </owl:unionOf>\n" +
" </owl:Class>\n" +
" </owl:unionOf>\n" +
" </owl:Class>\n" +
"</rdf:RDF>";
Model m = ModelFactory.createDefaultModel();
try (InputStream in = new ByteArrayInputStream(s.getBytes(StandardCharsets.UTF_8))) {
m.read(in, Lang.RDFXML.getLabel());
}
//m.write(System.out, "ttl");
m.listStatements()
.mapWith(Statement::getObject)
.filterKeep(RDFNode::isURIResource)
.mapWith(RDFNode::asResource)
.filterDrop(OWL.Class::equals)
.filterDrop(OWL.Ontology::equals)
.filterDrop(RDF.nil::equals)
.mapWith(Resource::getURI)
.forEachRemaining(System.out::println);
输出:
http://www.summyUrl.com/something#Entity1
http://www.summyUrl.com/something#Entity2
http://www.summyUrl.com/something#Entity1
这只是一个例子。有很多方法可以处理任何事情
我试过这样做,效果很好:
/**
* Explodes <b>Anonymous resource</b> (Collection resource) in recursive way and provides
* nested resources. Mainly considers <code>owl:unionOf</code>, <code>owl:intersactionOf</code>, <code>rdf:first</code> and <code>rdf:rest</code>
* while traversing.
*
* @param resource
* @return LinkedList<Resource>
*/
private List<Resource> explodeAnonymousResource(Resource resource)
{
private static List<Property> collectionProperties = new LinkedList<Property>(Arrays.asList(OWL.unionOf,OWL.intersectionOf,RDF.first,RDF.rest));
List<Resource> resources=new LinkedList<Resource>();
Boolean needToTraverseNext=false;
if(resource.isAnon())
{
for(Property cp:collectionProperties)
{
if(resource.hasProperty(cp) && !resource.getPropertyResourceValue(cp).equals(RDF.nil))
{
Resource nextResource=resource.getPropertyResourceValue(cp);
resources.addAll(explodeAnonymousResource(nextResource));
needToTraverseNext=true;
}
}
if(!needToTraverseNext)
{
resources.add(resource);
}
}
else
{
resources.add(resource);
}
return resources;
}