RDF在一行中列出主题及其对象 [英] RDF list subjects with their objects in a single line

查看:72
本文介绍了RDF在一行中列出主题及其对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个RDF文件,我需要从中提取一些信息并将其写入文件.我了解了它的基本工作原理,但我对此坚持下去:

I have an RDF file and I need to extract some information from it and write it to a file. I understood how it basically works, but I'm stuck with this:

String queryString = "select ?person ?children where { ?person ?hasChildren ?children}";
TupleQuery tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
TupleQueryResult result = tupleQuery.evaluate();     
while (result.hasNext()) {
    BindingSet bindingSet = result.next();
    Value p1 = bindingSet.getValue("person");
    Value p2 = bindingSet.getValue("child");
    println(p1 + " has children " + p2 +"");
}
result.close();

我得到的输出是这样的:

The output I get is like this:

http://example.org/people/person1 has children http://example.org/people/child1
http://example.org/people/person1 has children http://example.org/people/child2

我看不到如何以这种格式列出所有带有其对象的人:

I don't see how to list all the persons with their objects in this format:

person1 has children child1 and child2

这怎么办?

推荐答案

您可能会发现有用的答案,它描述了SPARQL的group_concat:

You may find this answer, which describes SPARQL's group_concat, useful:

在SPARQL中,当您拥有一组查询解决方案的结果时,可以对一个或多个变量进行group合并具有这些变量的解决方案.例如,考虑数据

In SPARQL, when you have a result set of query solutions, you can group on one or more of the variables, merging solutions that have these variables in common. For instance, consider the data

@prefix : <http://example.org/people/>.

:person1 :hasChild :child1, :child2, :child3 .
:person2 :hasChild :child4, :child5 .
:person3 :hasChild :child6 .

如果您对它运行以下查询

If you run the following query on it

prefix : <http://example.org/people/>

select ?person ?child where { 
  ?person :hasChild ?child .
}

您将获得如下结果:

$ arq --data data.n3 --query query.sparql
----------------------
| person   | child   |
======================
| :person3 | :child6 |
| :person2 | :child5 |
| :person2 | :child4 |
| :person1 | :child3 |
| :person1 | :child2 |
| :person1 | :child1 |
----------------------

按问题的顺序遍历结果将产生当前所获得的输出类型.我们要做的实际上是获得如下结果:

Iterating through the results as you have in your question would produce the type of output that you're currently getting. What we'd like to do is to actually get results like:

$ arq --data data.n3 --query query.sparql
----------------------------------------
| person   | child                     |
========================================
| :person3 | :child6                   |
| :person2 | :child4, :child5          |
| :person1 | :child1, :child2, :child3 |
----------------------------------------

而这正是group_by允许我们执行的操作.这样的查询:

and that's exactly what group_by lets us do. A query like this:

prefix : <http://example.org/people/>

select ?person (group_concat(?child;separator=' and ') as ?children) where { 
  ?person :hasChild ?child .
}
group by ?person

产生(注意结果中的变量是?children,而不是?child,因为我们已经使用group_concat(...) as ?children创建了新变量?children):

produces (notice that the variable in the result is ?children, not ?child, because we've used group_concat(...) as ?children to create the new variable ?children):

$ arq --data data.n3 --query query.sparql
---------------------------------------------------------------------------------------------------------------------------
| person   | children                                                                                                     |
===========================================================================================================================
| :person3 | "http://example.org/people/child6"                                                                           |
| :person1 | "http://example.org/people/child3 and http://example.org/people/child2 and http://example.org/people/child1" |
| :person2 | "http://example.org/people/child5 and http://example.org/people/child4"                                      |
---------------------------------------------------------------------------------------------------------------------------

如果使用这样的查询并遍历结果,然后按需打印,则会得到所需的输出.如果确实要从人和孩子中除去前导http://example.org/people/,则需要更多的字符串处理.例如,使用 STRAFTER 删除http://example.org/people/前缀,您可以使用如下查询:

If you use a query like this and iterate through the results, printing them as you have, you'll get output like you want. If you do want to strip the leading http://example.org/people/ off from the persons and children, you'll need a bit more string processing. For instance, using STRAFTER to remove the http://example.org/people/ prefix, you can use a query like this:

prefix : <http://example.org/people/>

select
 (strafter(str(?personX),"http://example.org/people/") as ?person)
 (group_concat(strafter(str(?child),"http://example.org/people/");separator=' and ') as ?children)
where { 
  ?personX :hasChild ?child .
}
group by ?personX

获得如下结果:

$ arq --data data.n3 --query query.sparql
----------------------------------------------
| person    | children                       |
==============================================
| "person3" | "child6"                       |
| "person2" | "child5 and child4"            |
| "person1" | "child3 and child2 and child1" |
----------------------------------------------

当您进行打印时,它会给您类似的结果

which, when you do your printing, will give you results like

person3 has children child6
person2 has children child5 and child4
person1 has children child3 and child2 and child1

这篇关于RDF在一行中列出主题及其对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆