简体   繁体   中英

Why is prefix replaced to ns2 when forming a SPARQL Construct query

I want to replace a property in my SPARQL result set by a CONSTRUCT, and it basically works, except that the prefix gets automatically replaced by "ns2". Does anyone know why, and how it can be avoided?

Head of query

" PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> " +
" PREFIX ma: <http://www.w3.org/ns/ma-ont#> " +
" PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> " +
" CONSTRUCT { ?subject ma:title ?label }  " +
 " WHERE { "+
 " ?subject rdfs:label ?label. " +

Example result:

<http://dbpedia.org/resource/Japantown,_San_Francisco> ns2:title  "Japantown, San Francisco"@en 

The Issue

For what it's worth, it doesn't look like Jena is doing this, but rather (assuming that the presence of a DBpedia resource means that you're querying DBpedia) DBpedia's endpoint. Given this simple data:

@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix ma: <http://www.w3.org/ns/ma-ont#> .

<http://dbpedia.org/resource/Japantown,_San_Francisco> rdfs:label  "Japantown, San Francisco"@en .

and this query:

PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ma: <http://www.w3.org/ns/ma-ont#>

CONSTRUCT { ?subject ma:title ?label }
WHERE { 
  ?subject rdfs:label ?label 
}

Jena's ARQ seems to preserve the prefix in both RDF/XML and TURTLE:

$ arq --data data.n3 --query construct.sparql --results RDF/XML
<rdf:RDF
    xmlns:ma="http://www.w3.org/ns/ma-ont#"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
  <rdf:Description rdf:about="http://dbpedia.org/resource/Japantown,_San_Francisco">
    <ma:title xml:lang="en">Japantown, San Francisco</ma:title>
  </rdf:Description>
</rdf:RDF>
$ arq --data data.n3 --query construct.sparql
@prefix rdfs:    <http://www.w3.org/2000/01/rdf-schema#> .
@prefix ma:      <http://www.w3.org/ns/ma-ont#> .

<http://dbpedia.org/resource/Japantown,_San_Francisco>
      ma:title      "Japantown, San Francisco"@en .

However, running a very similar query (note the VALUES that will keep our results small) run on the DBpedia public SPARQL endpoint gets the auto-generated namespace prefixes that you've mentioned.

PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ma: <http://www.w3.org/ns/ma-ont#>

CONSTRUCT { ?subject ma:title ?label }
WHERE { 
  VALUES ?subject { <http://dbpedia.org/resource/Japantown,_San_Francisco> }
  ?subject rdfs:label ?label 
}

SPARQL Results

@prefix ns0:    <http://www.w3.org/ns/ma-ont#> .
<http://dbpedia.org/resource/Japantown,_San_Francisco>  ns0:title   "Japantown, San Francisco"@en .

Note that these result are the same RDF graph ; the prefix is just a handy way to make some output more readable. Any RDF-processing tool will see that they are exactly the same graph. Jena's not doing anything wrong (and in fact, Jena's is nice in that it preserves the prefix), but neither is the Virtuoso instance that's running on DBpedia.

Preserving the prefix

While the prefixes only affect the human readability of a serialization of a graph, the human readability of a serialization of a graph can be important. There are some ways to preserve the prefix even though DBpedia has gone and changed it under you.

Using Federated Queries (SERVICE)

Using ARQ on the command line (as shown above) with the data available locally kept the desired prefix in the constructed model. We can write a similar query that actually queries DBpedia remotely, but since it's ARQ's job to actually construct the graph the prefixes end up the way you'd expect. For instance:

PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ma: <http://www.w3.org/ns/ma-ont#>

CONSTRUCT { ?subject ma:title ?label }
WHERE { 
  VALUES ?subject { <http://dbpedia.org/resource/Japantown,_San_Francisco> }
  SERVICE <http://dbpedia.org/sparql> {
    ?subject rdfs:label ?label 
  }
}

ARQ still requires a --data argument, so I created an empty file, empty-data.n3 . The data here that we want here is actually coming from DBpedia.

$ arq --data empty-data.n3 --query construct-remote.sparql
@prefix rdfs:    <http://www.w3.org/2000/01/rdf-schema#> .
@prefix ma:      <http://www.w3.org/ns/ma-ont#> .

<http://dbpedia.org/resource/Japantown,_San_Francisco>
      ma:title      "Japantown, San Francisco"@en .

Changing the Prefixes in a Jena Model (PrefixMapping)

Since a Jena Model is a PrefixMapping, you can change the prefixes that are used. Here's Java code that runs a remote query (without using the a federated query) and updates the prefixes afterward.

import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.vocabulary.RDFS;

public class RemoteQueryPrefixChange {
    final static String MA_NS = "http://www.w3.org/ns/ma-ont#";

    final static String queryString = "" +
            "PREFIX rdfs: <"+RDFS.getURI()+">\n" +
            "PREFIX ma: <"+MA_NS+">\n" +
            "\n" +
            "CONSTRUCT { ?subject ma:title ?label }\n" +
            "WHERE {\n" +
            "  VALUES ?subject { <http://dbpedia.org/resource/Japantown,_San_Francisco> }\n" +
            "  ?subject rdfs:label ?label\n" +
            "}\n" +
            ""; 

    final static String DBPEDIA_SERVICE = "http://dbpedia.org/sparql";

    public static void main(String[] args) {
        Model results = QueryExecutionFactory.sparqlService( DBPEDIA_SERVICE, queryString ).execConstruct();
        System.out.println( "== Original Prefixes ==" );
        results.write( System.out, "TTL" );
        System.out.println( "== Updated Prefixes ==" );
        results.removeNsPrefix( results.getNsURIPrefix( MA_NS ));
        results.setNsPrefix( "ma", MA_NS);
        results.write( System.out, "TTL" );
    }
}

The output is (notice the ns2 in the original serialization of the model, and ma in the updated serialization):

== Original Prefixes ==
@prefix ns2:     <http://www.w3.org/ns/ma-ont#> .
@prefix rdfs:    <http://www.w3.org/2000/01/rdf-schema#> .
@prefix rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .

<http://dbpedia.org/resource/Japantown,_San_Francisco>
      ns2:title "Japantown, San Francisco"@en .
== Updated Prefixes ==
@prefix rdfs:    <http://www.w3.org/2000/01/rdf-schema#> .
@prefix ma:      <http://www.w3.org/ns/ma-ont#> .
@prefix rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .

<http://dbpedia.org/resource/Japantown,_San_Francisco>
      ma:title "Japantown, San Francisco"@en .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM