java - 使用 Jena 迭代 RDF

标签 java rdf jena turtle-rdf

我现在正在做一个学习项目,我需要一些帮助。

基本上,我需要将以下 RDF 转换为 Java 类的表示。我将 RDF 读入一个模型,然后我就卡住了。

    StringReader in = new StringReader(resultTemp);
    Model model = ModelFactory.createDefaultModel();
    model.read(in, null, "TURTLE");

我尝试使用函数 listSubjectsWithProperty(Property arg0, RDFNode arg1) 和 StmtIterator,但我就是想不通。 如果能提供一些帮助,我将不胜感激。

RDF:

@prefix d: <http://www.w3.org/2001/XMLSchema#> .
@prefix p: <http://parking.kmi.open.ac.uk/ontologies/parking#> .
@prefix s: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix g: <http://www.w3.org/2003/01/geo/wgs84_pos#> .
@prefix o: <http://linkedgeodata.org/ontology/> .

<http://parking.kmi.open.ac.uk/data/parks/4751.3> a o:Parking ;
    g:lat "50.8509406"^^d:double ;
    g:long "-0.983707"^^d:double ;
    p:binaryAvailability "true"^^d:boolean .

<http://parking.kmi.open.ac.uk/data/parks/4934.6> a o:Parking ;
    g:lat "50.8737457"^^d:double ;
    g:long "-0.9731118"^^d:double ;
    p:binaryAvailability "true"^^d:boolean .

<http://parking.kmi.open.ac.uk/data/parks/4934.8> a o:Parking ;
    g:lat "50.873617"^^d:double ;
    g:long "-0.9722267"^^d:double ;
    p:binaryAvailability "true"^^d:boolean .

<http://parking.kmi.open.ac.uk/data/parks/4934.3> a o:Parking ;
    g:lat "50.8696495"^^d:double ;
    g:long "-0.9767757"^^d:double ;
    p:binaryAvailability "true"^^d:boolean .

<http://parking.kmi.open.ac.uk/data/parks/4934.2> a o:Parking ;
    g:lat "50.8698594"^^d:double ;
    g:long "-0.9775482"^^d:double ;
    p:binaryAvailability "true"^^d:boolean .

<http://parking.kmi.open.ac.uk/data/parks/4934.1> a o:Parking ;
    g:lat "50.8704349"^^d:double ;
    g:long "-0.9774731"^^d:double ;
    p:binaryAvailability "true"^^d:boolean .

<http://parking.kmi.open.ac.uk/data/parks/4934.7> a o:Parking ;
    g:lat "50.8732887"^^d:double ;
    g:long "-0.9725968"^^d:double ;
    p:binaryAvailability "true"^^d:boolean .

<http://parking.kmi.open.ac.uk/data/parks/28356.7> a o:Parking ;
    g:lat "50.997992"^^d:double ;
    g:long "-0.926222"^^d:double ;
    p:binaryAvailability "true"^^d:boolean .

<http://parking.kmi.open.ac.uk/data/parks/40865.5> a o:Parking ;
    g:lat "50.995467"^^d:double ;
    g:long "-1.036603"^^d:double ;
    s:label "Workhouse Lane" ;
    p:binaryAvailability "true"^^d:boolean .

<http://parking.kmi.open.ac.uk/data/parks/7185.1> a o:Parking ;
    g:lat "50.9885711"^^d:double ;
    g:long "-1.0811721"^^d:double ;
    p:binaryAvailability "true"^^d:boolean .

<http://parking.kmi.open.ac.uk/data/parks/33791.10> a o:Parking ;
    g:lat "50.887628"^^d:double ;
    g:long "-0.929626"^^d:double ;
    s:label "Locked at 17:30" ;
    p:binaryAvailability "true"^^d:boolean .

<http://parking.kmi.open.ac.uk/data/parks/20810.1> a o:Parking ;
    g:lat "50.891515"^^d:double ;
    g:long "-0.964029"^^d:double ;
    p:binaryAvailability "true"^^d:boolean .

<http://parking.kmi.open.ac.uk/data/parks/33791.11> a o:Parking ;
    g:lat "50.894162"^^d:double ;
    g:long "-0.927854"^^d:double ;
    s:label "Locked at 17:30" ;
    p:binaryAvailability "true"^^d:boolean .

<http://parking.kmi.open.ac.uk/data/parks/41308.7> a o:Parking ;
    g:lat "50.848336"^^d:double ;
    g:long "-0.937472"^^d:double ;
    p:binaryAvailability "true"^^d:boolean .

<http://parking.kmi.open.ac.uk/data/parks/41308.6> a o:Parking ;
    g:lat "50.849124"^^d:double ;
    g:long "-0.937969"^^d:double ;
    p:binaryAvailability "true"^^d:boolean .

<http://parking.kmi.open.ac.uk/data/parks/38470.10> a o:Parking ;
    g:lat "50.849454"^^d:double ;
    g:long "-0.939969"^^d:double ;
    p:binaryAvailability "true"^^d:boolean .

<http://parking.kmi.open.ac.uk/data/parks/33030.4> a o:Parking ;
    g:lat "50.850708"^^d:double ;
    g:long "-0.913150"^^d:double ;
    p:binaryAvailability "true"^^d:boolean .

<http://parking.kmi.open.ac.uk/data/parks/33030.3> a o:Parking ;
    g:lat "50.850421"^^d:double ;
    g:long "-0.914416"^^d:double ;
    p:binaryAvailability "true"^^d:boolean .

<http://parking.kmi.open.ac.uk/data/parks/41378.7> a o:Parking ;
    g:lat "50.851734"^^d:double ;
    g:long "-0.949425"^^d:double ;
    p:binaryAvailability "true"^^d:boolean .

<http://parking.kmi.open.ac.uk/data/parks/23937.9> a o:Parking ;
    g:lat "50.854045"^^d:double ;
    g:long "-0.979164"^^d:double ;
    p:binaryAvailability "true"^^d:boolean .

<http://parking.kmi.open.ac.uk/data/parks/23834.6> a o:Parking ;
    g:lat "50.849214"^^d:double ;
    g:long "-0.987087"^^d:double ;
    p:binaryAvailability "true"^^d:boolean .

<http://parking.kmi.open.ac.uk/data/parks/23937.8> a o:Parking ;
    g:lat "50.847012"^^d:double ;
    g:long "-0.986388"^^d:double ;
    p:binaryAvailability "true"^^d:boolean .

<http://parking.kmi.open.ac.uk/data/parks/23937.7> a o:Parking ;
    g:lat "50.845044"^^d:double ;
    g:long "-0.989708"^^d:double ;
    p:binaryAvailability "true"^^d:boolean .

<http://parking.kmi.open.ac.uk/data/parks/23937.12> a o:Parking ;
    g:lat "50.844084"^^d:double ;
    g:long "-1.008944"^^d:double ;
    p:binaryAvailability "true"^^d:boolean .

<http://parking.kmi.open.ac.uk/data/parks/30510.6> a o:Parking ;
    g:lat "50.821892"^^d:double ;
    g:long "-0.983163"^^d:double ;
    p:binaryAvailability "true"^^d:boolean .

<http://parking.kmi.open.ac.uk/data/parks/30554.10> a o:Parking ;
    g:lat "50.822039"^^d:double ;
    g:long "-0.982497"^^d:double ;
    p:binaryAvailability "true"^^d:boolean .

<http://parking.kmi.open.ac.uk/data/parks/25125.2> a o:Parking ;
    g:lat "50.825640"^^d:double ;
    g:long "-1.078993"^^d:double ;
    p:binaryAvailability "true"^^d:boolean .

<http://parking.kmi.open.ac.uk/data/parks/25125.1> a o:Parking ;
    g:lat "50.824621"^^d:double ;
    g:long "-1.082243"^^d:double ;
    p:binaryAvailability "true"^^d:boolean .

<http://parking.kmi.open.ac.uk/data/parks/25125> a o:Parking ;
    g:lat "50.824789"^^d:double ;
    g:long "-1.083873"^^d:double ;
    p:binaryAvailability "true"^^d:boolean .

<http://parking.kmi.open.ac.uk/data/parks/7345.6> a o:Parking ;
    g:lat "50.8249235"^^d:double ;
    g:long "-1.0734443"^^d:double ;
    s:label "Cycle-World" ;
    p:binaryAvailability "true"^^d:boolean .

<http://parking.kmi.open.ac.uk/data/parks/21282> a o:Parking ;
    g:lat "50.836295"^^d:double ;
    g:long "-1.071699"^^d:double ;
    p:binaryAvailability "true"^^d:boolean .

<http://parking.kmi.open.ac.uk/data/parks/25113.1> a o:Parking ;
    g:lat "50.829433"^^d:double ;
    g:long "-1.065990"^^d:double ;
    p:binaryAvailability "true"^^d:boolean .

<http://parking.kmi.open.ac.uk/data/parks/25125.5> a o:Parking ;
    g:lat "50.834706"^^d:double ;
    g:long "-1.074678"^^d:double ;
    p:binaryAvailability "true"^^d:boolean .

<http://parking.kmi.open.ac.uk/data/parks/29282.1> a o:Parking ;
    g:lat "50.836060"^^d:double ;
    g:long "-1.075153"^^d:double ;
    p:binaryAvailability "true"^^d:boolean .

<http://parking.kmi.open.ac.uk/data/parks/41323.3> a o:Parking ;
    g:lat "50.853264"^^d:double ;
    g:long "-0.990290"^^d:double ;
    p:binaryAvailability "true"^^d:boole...`

您好,我需要遍历这些 block 中的每一个:

<http://parking.kmi.open.ac.uk/data/parks/4751.3> a o:Parking ;
    g:lat "50.8509406"^^d:double ;
    g:long "-0.983707"^^d:double ;
    p:binaryAvailability "true"^^d:boolean .

是否有一些迭代器或其他方法允许我这样做?

最佳答案

如果您确实想手动迭代您关心的数据并手动选择您想要的数据,那么您可以使用 Jena 模型 API 来实现。但是,我认为使用 SPARQL 查询选择数据然后迭代生成的结果集会更容易。此答案的其余部分展示了如何实现这些方法中的每一种。

使用 Jena 模型 API

如果你想手动执行此操作,你可以这样做(评论解释了发生了什么):

import java.io.IOException;
import java.io.InputStream;

import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.ResIterator;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.vocabulary.RDF;
import com.hp.hpl.jena.vocabulary.RDFS;


public class ParkingExample {
    public static void main(String[] args) throws IOException {
        // Read the model from whereever it comes from.  For this example, 
        // I made a local copy in parking.ttl and so I'm loading it as a 
        // resource.  You're already able to load the model, so this 
        // isn't so important.
        Model model = ModelFactory.createDefaultModel();
        try ( final InputStream in = ParkingExample.class.getResourceAsStream( "/parking.ttl" ) ) {
            model.read( in, null, "TTL" );
        }

        // Create some properties in advance for convenience.
        final Property g_lat = model.createProperty( "http://www.w3.org/2003/01/geo/wgs84_pos#lat" );
        final Property g_long = model.createProperty( "http://www.w3.org/2003/01/geo/wgs84_pos#long" );
        final Property p_binaryAvailability = model.createProperty( "http://parking.kmi.open.ac.uk/ontologies/parking#binaryAvailability" );

        // In N3, Turtle, and SPARQL, `a` is a shorthand for rdf:type.  That means
        // that each of the triples of the form 
        //
        //   <http://parking.kmi.open.ac.uk/data/parks/4934.1> a o:Parking
        //
        // is saying that the subject has rdf:type o:Parking.  That's how we'll retrieve
        // these resources.  We'll select subjects that have o_Parking as a value for 
        // rdf:type.  We'll predefine o_Parking for convenience.
        final Resource o_Parking = model.createResource( "http://linkedgeodata.org/ontology/Parking" );

        // Now we get an iterator over the resources that have type o_Parking.
        for ( final ResIterator res = model.listResourcesWithProperty( RDF.type, o_Parking ); res.hasNext(); ) {
            final Resource r = res.next();

            // For each one of them, it appears that they have a mandatory lat, lon, and binAvailability, 
            // so we can retrieve those values, assuming that they'll be there.
            final float lat = r.getRequiredProperty( g_lat ).getObject().asLiteral().getFloat();
            final float lon = r.getRequiredProperty( g_long ).getObject().asLiteral().getFloat();
            final boolean binAvailibility = r.getRequiredProperty( p_binaryAvailability ).getObject().asLiteral().getBoolean();

            // Some of the Parkings have an rdfs:label, but not all of them do.  For this, we'll retrieve
            // a statement, but since there might not be one, we have to check whether it's null.  If it 
            // is, then we'll make the label null, but otherwise we'll get the string value out of it.
            final Statement s = r.getProperty( RDFS.label );
            final String label = s == null ? null : s.getObject().asLiteral().getString();

            // Now you can do whatever you want with these values.  You could create an instance of another 
            // class, for instance.. I'll just print the values out.
            System.out.println( r + ":" +
                    "\n\tlatitude: " + lat +
                    "\n\tlongitude: " + lon +
                    "\n\tavailibility: " + binAvailibility +
                    "\n\tlabel: " + label );
        }
    }
}

这会产生如下输出:

http://parking.kmi.open.ac.uk/data/parks/4751.3:
    latitude: 50.85094
    longitude: -0.983707
    availibility: true
    label: null
http://parking.kmi.open.ac.uk/data/parks/41378.7:
    latitude: 50.851734
    longitude: -0.949425
    availibility: true
    label: null
http://parking.kmi.open.ac.uk/data/parks/25125:
    latitude: 50.824787
    longitude: -1.083873
    availibility: true
    label: null
…

使用 SPARQL 查询

我认为使用 SPARQL 查询更容易做到这一点。 SPARQL 查询让您可以准确地写入您要查找的数据类型,包括可选值,并且您可以使用 ResultSet API 获取您想要返回的特定值。在这种情况下,您需要这样的查询:

prefix d: <http://www.w3.org/2001/XMLSchema#>
prefix p: <http://parking.kmi.open.ac.uk/ontologies/parking#>
prefix s: <http://www.w3.org/2000/01/rdf-schema#>
prefix g: <http://www.w3.org/2003/01/geo/wgs84_pos#>
prefix o: <http://linkedgeodata.org/ontology/>

select ?parking ?lat ?lon ?availability ?label where {
  ?parking a o:Parking ;
             g:lat ?lat ;
             g:long ?lon ;
             p:binaryAvailability ?availability .
  optional { ?parking s:label ?label }
}

下面是如何在代码中使用它:

import java.io.IOException;
import java.io.InputStream;

import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;


public class ParkingExample {
    public static void main(String[] args) throws IOException {

        final String query = 
         "prefix d: <http://www.w3.org/2001/XMLSchema#>\n" +
         "prefix p: <http://parking.kmi.open.ac.uk/ontologies/parking#>\n" +
         "prefix s: <http://www.w3.org/2000/01/rdf-schema#>\n" +
         "prefix g: <http://www.w3.org/2003/01/geo/wgs84_pos#>\n" +
         "prefix o: <http://linkedgeodata.org/ontology/>\n" +
         "\n" +
         "select ?parking ?lat ?lon ?availability ?label where {\n" +
         "  ?parking a o:Parking ;\n" +
         "             g:lat ?lat ;\n" +
         "             g:long ?lon ;\n" +
         "             p:binaryAvailability ?availability .\n" +
         "  optional { ?parking s:label ?label }\n" +
         "}";

        Model model = ModelFactory.createDefaultModel();
        try ( final InputStream in = ParkingExample.class.getResourceAsStream( "/parking.ttl" ) ) {
            model.read( in, null, "TTL" );
        }

        final QueryExecution exec = QueryExecutionFactory.create( query, model );
        final ResultSet rs = exec.execSelect();
        while ( rs.hasNext() ) {
            final QuerySolution qs = rs.next();
            System.out.println( qs.get( "parking" ) +
                    "\n\t" + qs.get( "lat" ) +
                    "\n\t" + qs.get( "lon" ) +
                    "\n\t" + qs.get( "availability" ) +
                    "\n\t" + qs.get( "label" ));
        }
    }
}

输出是:

http://parking.kmi.open.ac.uk/data/parks/38470.10
    50.849454^^http://www.w3.org/2001/XMLSchema#double
    -0.939969^^http://www.w3.org/2001/XMLSchema#double
    true^^http://www.w3.org/2001/XMLSchema#boolean
    null
http://parking.kmi.open.ac.uk/data/parks/28356.7
    50.997992^^http://www.w3.org/2001/XMLSchema#double
    -0.926222^^http://www.w3.org/2001/XMLSchema#double
    true^^http://www.w3.org/2001/XMLSchema#boolean
    null
http://parking.kmi.open.ac.uk/data/parks/33791.11
    50.894162^^http://www.w3.org/2001/XMLSchema#double
    -0.927854^^http://www.w3.org/2001/XMLSchema#double
    true^^http://www.w3.org/2001/XMLSchema#boolean
    Locked at 17:30
…

关于java - 使用 Jena 迭代 RDF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20453082/

相关文章:

Java:将 TextField 保存到另一个类中使用的字符串

java - 生成 Jena Bnode ID

rdf - Fuseki 可以同时使用 OWL 推理器和规则推理器吗

java - 通过 BlazeDS 将自定义 Java 对象的 ArrayList 导入 AS3.0

java - 如何将列表转换为 map ?

java - Android模拟器与本地mysql数据库连接的方法

datetime - 按 SPARQL 中的日期范围过滤

python - 数据追加到芝麻存储库

validation - 如何验证 CIM RDF

sparql - 使用字符串形式的非负整数对 sparql 中的结果进行升序排列