如何在RDF中存储带有序子项的树?如何在SPARQL中遍历这样的结构?

问题描述 投票:2回答:2

如何在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?”没有回答我的问题。它讨论了无序节点。我的问题是关于有序收集(列表清单)和按原始顺序取回元素。

sparql rdf virtuoso
2个回答
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" 
                ]
            )
        ]
    ) .

选项2

另一个选择是依赖存储顺序,希望项目按照外观顺序存储。

blank node property listscollections的龟语法强制纠正“出现顺序”。

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

选项3

另一种选择是使用推理。

  1. 首先,让我们为有序树发明我们自己的格式,例如: 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.
  2. 其次,让我们恢复初始树排序(并传递关闭它)。在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公理代替或明确断言一些推断语句。
  3. 第三,让我们制定规则,定义与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) 不确定这套规则是否简洁或优雅......
  4. 现在,您的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)
© www.soinside.com 2019 - 2024. All rights reserved.