Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading nested RDF Triples in Jena

I have a query

CONSTRUCT { ?highValForeignTran ?hvFTPred ?hvFTObj . }
WHERE { ?highValForeignTran vocab:accounttransactions_transactionCurrency "USD" .
?highValForeignTran vocab:accounttransactions_transactionValue ?tranValue .
?highValForeignTran vocab:accounttransactions_transactionDate ?tranDate .
?highValForeignTran ?hvFTPred ?hvFTObj .
FILTER ( ?tranValue > 10000) .
FILTER (  ?tranDate >= "2013-11-23"^^xsd:date  && ?tranDate <= "2013-11-23"^^xsd:date) .
}

that returns the result:

<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:vocab="http://localhost:2020/resource/vocab/"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:db="http://localhost:2020/resource/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:map="http://localhost:2020/resource/#">
<vocab:accounttransactions rdf:about="http://localhost:2020/resource/accounttransactions/1">
<vocab:accounttransactions_id rdf:datatype="http://www.w3.org/2001/XMLSchema#integer"
>1</vocab:accounttransactions_id>
<vocab:accounttransactions_transactionCurrency>USD</vocab:accounttransactions_transactionCurrency>
<vocab:accounttransactions_originAccountNumber>DB48939239</vocab:accounttransactions_originAccountNumber>
<vocab:accounttransactions_transactionType>Cr</vocab:accounttransactions_transactionType>
    <vocab:accounttransactions_transactionDate rdf:datatype="http://www.w3.org/2001/XMLSchema#date"
>2013-11-23</vocab:accounttransactions_transactionDate>
<vocab:accounttransactions_destinationAccountId rdf:resource="http://localhost:2020/resource/bankaccounts/1"/>
<vocab:accounttransactions_transactionValue rdf:datatype=
"http://www.w3.org/2001/XMLSchema#decimal">12000</vocab:accounttransactions_transactionValue>
<rdfs:label>accounttransactions #1</rdfs:label>
<vocab:accounttransactions_destinationAccountNumber>47321896544567</vocab:accounttransactions_destinationAccountNumber>
</vocab:accounttransactions>
</rdf:RDF>

when I try to parse this using Jena however I only get one triple that represents the outer accountTransactions triple:

{"http://localhost:2020/resource/accounttransactions/1":
 {"subject":"http://localhost:2020/resource/accounttransactions/1",
  "predicate":"http://www.w3.org/1999/02/22-rdf-syntax-ns#type",
  "object":"http://localhost:2020/resource/vocab/accounttransactions"}
}

I have no idea why the other triples get nested inside, but I really need to be able to parse them and send them as JSON. Here's my code:

try {
Model result = qexec.execConstruct();

    JSONObject jsonShell = new JSONObject();

StmtIterator stmtIter = model.listStatements();
    while ( stmtIter.hasNext() ) {
        Statement stmt = stmtIter.nextStatement();
        JSONObject innerJson = new JSONObject();
        innerJson.put("subject", stmt.getSubject().visitWith(rdfVisitor));
        innerJson.put("predicate", stmt.getPredicate().visitWith(rdfVisitor));
        innerJson.put("object", stmt.getObject().visitWith(rdfVisitor));

        jsonShell.put(String.valueOf(stmt.getSubject().visitWith(rdfVisitor)), innerJson);
    }
    System.out.println(resultJson.toString());
    }
    finally {
        qexec.close();
    }

RDFVisitor rdfVisitor = new RDFVisitor() {

    @Override
    public Object visitURI(Resource r, String uri) {
        return uri;
    }

    @Override
    public Object visitLiteral(Literal l) {
        return l.getLexicalForm();
    }

    @Override
    public Object visitBlank(Resource r, AnonId id) {
        return id.getLabelString();
    }
};

I wonderered if Statement.getProperty() might do the trick, but couldn't discover a way to create a Property instance.

like image 277
Nikhil Silveira Avatar asked Dec 05 '13 12:12

Nikhil Silveira


1 Answers

The problem in your code (and the resulting JSON)

All the triples in your data (which is fine) have the same subject. This might be easier to see in the In the more human readable Turtle format, or very explicitly in the one-triple-per-line N-Triples format. I've included these at the end of this answer. Since all the triples have the same subject, I suspect that what's happening is that

jsonShell.put(String.valueOf(stmt.getSubject().visitWith(rdfVisitor)), innerJson);
//            |-----------------------------------------------------|
//                         same every time

is overwriting the results of the previous iteration each time, since, as noted, the key is the same for each iteration. If you add some printing statements to your loop, I expect that you'll see that you are, in fact, iterating over every triple in your model.

I can't tell you what you ought to use for the key there, because I'm not clear how that key will be helpful, since the subject of the triple is already encoded in the output. It seems like you want some kind of statement ID, so maybe you could use a string representation the statement or something.

An alternative using Jena and RDF/JSON

I'd point out that Jena can serialize a model in RDF/JSON, and that might be an easier way for you to get JSON if that's what you need. The structure won't be the same as what you were generating of course, but that might not be a big problem. For instance, where /jsonoutput.ttl is my local copy of your data, the following code writes JSON.

import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;

public class JSONObjectTest {
    public static void main(String[] args) {
        Model model = ModelFactory.createDefaultModel();
        model.read( JSONObjectTest.class.getResourceAsStream( "/jsonoutput.ttl"), null, "N3" );
        model.write( System.out, "RDF/JSON" );
    }
}

The resuling JSON is:

{ 
  "http://localhost:2020/resource/accounttransactions/1" : { 
    "http://localhost:2020/resource/vocab/accounttransactions_transactionDate" : [ { 
      "type" : "literal" ,
      "value" : "2013-11-23" ,
      "datatype" : "http://www.w3.org/2001/XMLSchema#date"
    }
     ] ,
    "http://localhost:2020/resource/vocab/accounttransactions_transactionValue" : [ { 
      "type" : "literal" ,
      "value" : "12000" ,
      "datatype" : "http://www.w3.org/2001/XMLSchema#decimal"
    }
     ] ,
    "http://localhost:2020/resource/vocab/accounttransactions_id" : [ { 
      "type" : "literal" ,
      "value" : "1" ,
      "datatype" : "http://www.w3.org/2001/XMLSchema#integer"
    }
     ] ,
    "http://localhost:2020/resource/vocab/accounttransactions_destinationAccountNumber" : [ { 
      "type" : "literal" ,
      "value" : "47321896544567"
    }
     ] ,
    "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" : [ { 
      "type" : "uri" ,
      "value" : "http://localhost:2020/resource/vocab/accounttransactions"
    }
     ] ,
    "http://localhost:2020/resource/vocab/accounttransactions_transactionCurrency" : [ { 
      "type" : "literal" ,
      "value" : "USD"
    }
     ] ,
    "http://www.w3.org/2000/01/rdf-schema#label" : [ { 
      "type" : "literal" ,
      "value" : "accounttransactions #1"
    }
     ] ,
    "http://localhost:2020/resource/vocab/accounttransactions_transactionType" : [ { 
      "type" : "literal" ,
      "value" : "Cr"
    }
     ] ,
    "http://localhost:2020/resource/vocab/accounttransactions_destinationAccountId" : [ { 
      "type" : "uri" ,
      "value" : "http://localhost:2020/resource/bankaccounts/1"
    }
     ] ,
    "http://localhost:2020/resource/vocab/accounttransactions_originAccountNumber" : [ { 
      "type" : "literal" ,
      "value" : "DB48939239"
    }
     ]
  }
}

Your data in different formats

Data in Turtle/N3

@prefix db:    <http://localhost:2020/resource/> .
@prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl:   <http://www.w3.org/2002/07/owl#> .
@prefix xsd:   <http://www.w3.org/2001/XMLSchema#> .
@prefix map:   <http://localhost:2020/resource/#> .
@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix vocab: <http://localhost:2020/resource/vocab/> .

<http://localhost:2020/resource/accounttransactions/1>
        a                             vocab:accounttransactions ;
        rdfs:label                    "accounttransactions #1" ;
        vocab:accounttransactions_destinationAccountId
                <http://localhost:2020/resource/bankaccounts/1> ;
        vocab:accounttransactions_destinationAccountNumber
                "47321896544567" ;
        vocab:accounttransactions_id  1 ;
        vocab:accounttransactions_originAccountNumber
                "DB48939239" ;
        vocab:accounttransactions_transactionCurrency
                "USD" ;
        vocab:accounttransactions_transactionDate
                "2013-11-23"^^xsd:date ;
        vocab:accounttransactions_transactionType
                "Cr" ;
        vocab:accounttransactions_transactionValue
                "12000"^^xsd:decimal .

Data in N-Triples

<http://localhost:2020/resource/accounttransactions/1> <http://localhost:2020/resource/vocab/accounttransactions_id> "1"^^<http://www.w3.org/2001/XMLSchema#integer> .
<http://localhost:2020/resource/accounttransactions/1> <http://localhost:2020/resource/vocab/accounttransactions_transactionCurrency> "USD" .
<http://localhost:2020/resource/accounttransactions/1> <http://localhost:2020/resource/vocab/accounttransactions_originAccountNumber> "DB48939239" .
<http://localhost:2020/resource/accounttransactions/1> <http://localhost:2020/resource/vocab/accounttransactions_transactionType> "Cr" .
<http://localhost:2020/resource/accounttransactions/1> <http://localhost:2020/resource/vocab/accounttransactions_transactionDate> "2013-11-23"^^<http://www.w3.org/2001/XMLSchema#date> .
<http://localhost:2020/resource/accounttransactions/1> <http://localhost:2020/resource/vocab/accounttransactions_destinationAccountId> <http://localhost:2020/resource/bankaccounts/1> .
<http://localhost:2020/resource/accounttransactions/1> <http://localhost:2020/resource/vocab/accounttransactions_transactionValue> "12000"^^<http://www.w3.org/2001/XMLSchema#decimal> .
<http://localhost:2020/resource/accounttransactions/1> <http://www.w3.org/2000/01/rdf-schema#label> "accounttransactions #1" .
<http://localhost:2020/resource/accounttransactions/1> <http://localhost:2020/resource/vocab/accounttransactions_destinationAccountNumber> "47321896544567" .
<http://localhost:2020/resource/accounttransactions/1> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://localhost:2020/resource/vocab/accounttransactions> .
like image 68
Joshua Taylor Avatar answered Oct 01 '22 02:10

Joshua Taylor