如何在RDF中存储带有顺序子项的树?
输入:
1. Title 1 Some text 1. 2. Title 2 2.1. Title 2.1 Some text under title 2.1. 2.2. Title 2.2 Some text under title 2.2.
标题可以是任意的,不一定包含编号。
如何取回在一个查询中仍排序的所有元素?
所需的输出:
|-----------+----------------------------+ | Title | Content | |-----------+----------------------------+ | Title 1 | Some text under title 1. | | Title 2 | | | Title 2.1 | Some text under title 2.1. | | Title 2.2 | Some text under title 2.2. | |-----------+----------------------------+
编辑:“ Calculate length of path between nodes?”没有回答我的问题。它讨论了无序节点。我的问题特别是关于有序集合(列表列表)和按原始顺序获取元素。
答案 0 :(得分:2)
您可以按以下方式对示例数据进行建模:
ex:title1 a ex:Title ;
rdfs:label "Title 1";
rdfs:comment "some text under title 1".
ex:title2 a ex:Title ;
rdfs:label "Title 2";
rdfs:comment "some text under title 2".
ex:title21 a ex:Title ;
rdfs:label "Title 2.1";
rdfs:comment "some text under title 2.1".
ex:title22 a ex:Title ;
rdfs:label "Title 2.2";
rdfs:comment "some text under title 2.2".
ex:title2 ex:subtitles (ex:title21 ex:title22).
ex:titleCollection ex:subtitles (ex:title1 ex:title2) .
然后按顺序查询所有事物可以按标题进行非常基本的词汇排序:
select ?title ?content
where {
[] ex:subtitles/rdf:rest*/rdf:first [
rdfs:label ?title ;
rdfs:comment ?content ] .
}
order by ?title
结果:
Evaluating SPARQL query...
+-------------------------------------+-------------------------------------+
| title | content |
+-------------------------------------+-------------------------------------+
| "Title 1" | "some text under title 1" |
| "Title 2" | "some text under title 2" |
| "Title 2.1" | "some text under title 2.1" |
| "Title 2.2" | "some text under title 2.2" |
+-------------------------------------+-------------------------------------+
4 result(s) (4 ms)
如果您不想依赖实际的title属性来提供正确的排序,则可以当然地引入带有分层编号的显式排序属性,并在order by
子句中使用该值。
答案 1 :(得分:1)
您可以将RDF序列化为flattened JSON-LD并在e中编写简单的递归函数。 G。 Javascript。
var nquads = `
<http://ex.com/titleCollection> <http://ex.com/subtitles> _:b1 .
_:b1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> _:b2 .
_:b1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:b3 .
_:b2 <http://www.w3.org/2000/01/rdf-schema#label> "Title 1" .
_:b2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://ex.com/Title> .
_:b2 <http://www.w3.org/2000/01/rdf-schema#comment> "some text under title 1" .
_:b3 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> _:b4 .
_:b3 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> .
_:b4 <http://ex.com/subtitles> _:b5 .
_:b4 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://ex.com/Title> .
_:b4 <http://www.w3.org/2000/01/rdf-schema#comment> "some text under title 2" .
_:b4 <http://www.w3.org/2000/01/rdf-schema#label> "Title 2" .
_:b5 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> _:b6 .
_:b5 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:b7 .
_:b6 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://ex.com/Title> .
_:b6 <http://www.w3.org/2000/01/rdf-schema#comment> "some text under title 2.1" .
_:b6 <http://www.w3.org/2000/01/rdf-schema#label> "Title 2.1" .
_:b7 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> _:b8 .
_:b7 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> .
_:b8 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://ex.com/Title> .
_:b8 <http://www.w3.org/2000/01/rdf-schema#comment> "some text under title 2.2" .
_:b8 <http://www.w3.org/2000/01/rdf-schema#label> "Title 2.2" .
`;
jsonld.fromRDF(nquads, {format: 'application/nquads'}, function (err, doc) {
print(doc, "http://ex.com/titleCollection")
});
function print(doc, id) {
var what = get(doc, id)
var label = what['http://www.w3.org/2000/01/rdf-schema#label']
var comment = what['http://www.w3.org/2000/01/rdf-schema#comment']
var subtitles = what['http://ex.com/subtitles']
if (label) console.log(label[0]['@value'])
if (comment) console.log(comment[0]['@value'])
if (subtitles) {
for (var i of subtitles[0]['@list']) print(doc, i['@id'])
}
}
function get(doc, id) {return doc.find((element) => (element['@id'] == id))}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsonld/0.4.12/jsonld.min.js"></script>
原始海龟是:
@prefix ex: <http://ex.com/> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
ex:titleCollection ex:subtitles
(
[
a ex:Title ; rdfs:label "Title 1" ;
rdfs:comment "some text under title 1"
]
[
a ex:Title ; rdfs:label "Title 2" ;
rdfs:comment "some text under title 2" ;
ex:subtitles
(
[
a ex:Title ; rdfs:label "Title 2.1" ;
rdfs:comment "some text under title 2.1"
]
[
a ex:Title ; rdfs:label "Title 2.2" ;
rdfs:comment "some text under title 2.2"
]
)
]
) .
另一种选择是依靠存储顺序,希望按外观顺序存储项目。
blank node property lists和collections的Turtle语法强制正确的“出现顺序”。
在GraphDB中,您可以在导入上述Turtle之后说:
PREFIX ex: <http://ex.com/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ent: <http://www.ontotext.com/owlim/entity#>
SELECT ?label ?comment {
?s a ex:Title ; rdfs:label ?label ; rdfs:comment ?comment
} ORDER BY ent:id(?s)
另一种选择是使用推理。
首先,让我们发明自己的有序树格式,例如e。 G。以下之一:
:title0 a :Node; rdfs:label "Book";
:down title1.
:title1 a :Node; rdfs:label "Title 1";
:down title11;
:right title2.
:title2 a :Node; rdfs:label "Title 2";
:down title21;
:right title3.
:title3 a :Node; rdfs:label "Title 3";
:down title31.
第二,让我们恢复树的初始顺序(并暂时关闭它)。在SWRL中:
right(?a, ?b) ^ right(?b, ?c) -> right(?a, ?c)
down(?a, ?b) ^ right(?b, ?c) -> down(?a, ?c)
down(?a, ?b) ^ down(?b, ?c) -> down(?a, ?c)
您可以改用OWL公理,也可以显式声明一些推断的语句。
第三,让我们制定规则来定义与depth-first遍历顺序相对应的顺序:
right(?a, ?b) -> after(?a, ?b)
down(?a, ?b) -> after(?a, ?b)
down(?a, ?c) ^ right(?a, ?b) ^ down(?b, ?d) -> after(?c, ?d)
down(?a, ?c) ^ right(?a, ?b) -> after(?c, ?b)
right(?a, ?b) ^ down(?b, ?c) -> after(?a, ?c)
不确定这套规则是最小还是优雅...
现在,您的SPARQL查询应该是:
SELECT ?s (SAMPLE(?label) AS ?title) (COUNT(?o) AS ?count) {
?s a :Node ; rdfs:label ?label .
OPTIONAL { ?s :after ?o }
} GROUP BY ?s ORDER BY DESC(?count)