【问题标题】:Reading nested RDF Triples in Jena在耶拿读取嵌套的 RDF 三元组
【发布时间】:2023-04-03 21:01:01
【问题描述】:

我有一个问题

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) .
}

返回结果:

<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>

当我尝试使用 Jena 解析它时,我只得到一个代表外部 accountTransactions 三元组的三元组:

{"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"}
}

我不知道为什么其他三元组会嵌套在其中,但我确实需要能够解析它们并将它们作为 JSON 发送。 这是我的代码:

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();
    }
};

我想知道Statement.getProperty() 是否可以解决问题,但找不到创建Property 实例的方法。

【问题讨论】:

  • 其他三元组没有“嵌套在里面”。这只是 RDF/XML 的一种编写方式。 Turtle 中的 RDF 看起来像 pastebin.com/yU80Kqf8 。你得到了很好的数据。
  • 我没用过 JSONObjects,但是jsonShell.put("X", innerJson); 会在 JSON 中添加一堆“X”元素,还是继续覆盖之前的?此模型中的所有三元组都具有相同的主题,因此如果您正在执行 jsonShell.put(&lt;subject-uri&gt;,innerJson) 并且覆盖了现有条目,那么您最终只会得到一个。
  • 最好提及您正在使用的 JSON 库。我有一个加载了 Jena 的项目,但我没有任何 JSONObject 的自动完成功能……
  • @JoshuaTaylor:这是 Douglas Crockford 的 JSON-java。关于 put 覆盖,您可能是对的。我只是假设由于三元组是嵌套的,我的代码无法访问它们。我的错。明天早上我回到我的项目后会尽快验证这一点。非常感谢。

标签: java json rdf sparql jena


【解决方案1】:

代码中的问题(以及生成的 JSON)

您数据中的所有三元组(这很好)都有相同的主题。这在人类可读性更强的 Turtle 格式中可能更容易看到,或者在每行一个三重 N-Triples 格式中非常明确。我在这个答案的末尾包含了这些。由于所有三元组都有相同的主题,我怀疑正在发生的事情是

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

每次都会覆盖上一次迭代的结果,因为如前所述,每次迭代的关键是相同。如果您在循环中添加一些打印语句,我希望您会看到实际上您正在迭代模型中的每个三元组。

我无法告诉您应该使用什么作为那里的密钥,因为我不清楚该密钥将如何有用,因为三元组的主题已经编码在输出。似乎您想要某种语句 ID,所以也许您可以使用字符串表示语句或其他东西。

使用 Jena 和 RDF/JSON 的替代方法

我要指出的是,Jena 可以在 RDF/JSON 中序列化模型,如果您需要,这可能是您获取 JSON 的一种更简单的方法。当然,结构与您生成的结构不同,但这可能不是大问题。例如,/jsonoutput.ttl 是我的本地数据副本,以下代码写入 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" );
    }
}

生成的 JSON 是:

{ 
  "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"
    }
     ]
  }
}

不同格式的数据

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 .

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> .

【讨论】:

  • 你是对的,主题是相同的,并且一个 JSON 对象是一个关联数组,put 方法每次都会覆盖前一个键(主题)条目。也感谢您对 RDF JSON 的建议。目标是使用 JSON 来呈现图形,因此使用 RDFDataMgr.write(baos, result.getGraph(), Lang.RDFJSON) ; 对我来说也适用。
猜你喜欢
  • 1970-01-01
  • 2011-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多