【问题标题】:Dynamic Array in RDF/XMLRDF/XML 中的动态数组
【发布时间】:2015-04-16 08:41:18
【问题描述】:

在 c# 中,我正在生成一个图形并使用 RDF/XML 将其发送到我的 android 应用程序。我的图表的一部分应该显示到达某个火车站的不同火车。 添加一列火车,它的到达、出发、目的地等都没有问题。不幸的是,我不知道如何在 RDF/XML 中获取不同火车经过的所有车站。

例如:

  • A 列车从 1 号城市出发,经过 2 号和 3 号城市,然后到达 4 号城市。
  • B 列车从 1 号城市出发,经过 5、6 和 7 号城市,到达 8 号城市。

如何将 [city 5, city 6, city 7] 等数组动态添加到火车上?

我当前的 RDF/XML:

    <?xml version="1.0" encoding="utf-16"?>" +
                "<!DOCTYPE rdf:RDF [\n" +
                "\t<!ENTITY rdf 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'>\n" +
                "]>\n" +
                "<rdf:RDF xmlns:rdfs=\"http://www.w3.org/2000/01/rdf-schema#\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema#\" xmlns:ns0=\"http://my.url.com/ontologies/mash-up#\" xmlns:ns1=\"http://xmlns.com/foaf/0.1/\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n" +
                "  <ns0:Train rdf:about=\"http://my.url.com/ontologies/mash-up#Train-1d4b674c-479c-48a3-aab3-b729fc96cbd4\">\n" +
                "    <ns0:name rdf:datatype=\"&xsd;string\">RE 1</ns0:name>\n" +
                "    <ns0:description rdf:datatype=\"&xsd;string\">Platform 1</ns0:description>\n" +
                "    <ns0:arrival rdf:datatype=\"&xsd;dateTime\">2015-04-14T18:00:40Z</ns0:arrival>\n" +
                "    <ns0:departure rdf:datatype=\"&xsd;dateTime\">2015-04-14T18:02:40Z</ns0:departure>\n" +
                "    <ns0:destination rdf:datatype=\"&xsd;string\">Padaborn</ns0:destination>\n" +
                "    <ns1:primaryTopic rdf:resource=\"http://my.url.com/ontologies/mash-up#Train-1d4b674c-479c-48a3-aab3-b729fc96cbd4\" />\n" +
                "  </ns0:Train>\n" +
                "</rdf:RDF>";

简单地将所有站点添加为自己的属性意味着我的 Jena 查询必须有非常多的选项,我想避免这种情况。

提前致谢。

编辑: 我就是这样做的。这将意味着很多选项...

" <ns0:stations rdf:about=\"http://my.url.com/ontologies/mash-up#Stations-xxxx\">“+
"   <ns0:from rdf:datatype=\"&xsd;string\">Aachen</ns0:from>\n“ +
"   <ns0:to rdf:datatype=\"&xsd;string\">Padaborn</ns0:to>\n“ +
"   <ns0:over1 rdf:datatype=\"&xsd;string\“>Köln</ns0:to>\n“ +
"   <ns0:over2 rdf:datatype=\"&xsd;string\“>Düsseldorf</ns0:to>\n“ +
"   <ns0:over3 rdf:datatype=\"&xsd;string\“>Duisburg</ns0:to>\n“ +
"   <ns0:over4 rdf:datatype=\"&xsd;string\“>Essen</ns0:to>\n“ +
"   <ns0:over5 rdf:datatype=\"&xsd;string\“>Dortmund</ns0:to>\n“ +
"   <ns0:over6 rdf:datatype=\"&xsd;string\“>Hamm (Westf)</ns0:to>\n“ +
" </ns0:stations>\n"

【问题讨论】:

  • 您可以使用 RDF 列表(或其他集合)。请注意,实际上并不推荐手动构建 RDF/XML。 RDF/XML 只是 RDF 的一种序列化格式。通常使用 RDF 库或人类可读的格式来编写 RDF 会更容易,然后以您需要的任何格式进行序列化。
  • 但是查询,你仍然只需要一个“可选”
  • 请看我的编辑。如果没有太多的选项,我怎样才能实现这样的目标?我正在为我的单身汉处理别人的硕士论文的架构。他决定手动做所有事情,所以我必须使用我所拥有的......

标签: java graph rdf sparql jena


【解决方案1】:

如果电台的顺序不影响

最简单的选择是,如果通过的站点的顺序很重要,则使用 same 属性。这在数据中看起来像这样(我将使用 Turtle,因为它更具人类可读性和可写性,但也显示相应的 RDF/XML;两者之间的转换很容易,因为它们只是相同的不同序列化数据):

@prefix : <urn:train:>.
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.

:train1
  :name "RE 1" ;
  :description "Platform 1" ;
  :arrival "2015-04-14T18:00:40Z"^^xsd:dateTime ;
  :departure "2015-04-14T18:02:40Z"^^xsd:dateTime ;
  :over "Station1", "Station2", "Station3" ;
  :destination "Padaborn" .
<rdf:RDF
    xmlns="urn:train:"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema#">
  <rdf:Description rdf:about="urn:train:train1">
    <name>RE 1</name>
    <description>Platform 1</description>
    <arrival rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime"
    >2015-04-14T18:00:40Z</arrival>
    <departure rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime"
    >2015-04-14T18:02:40Z</departure>
    <over>Station1</over>
    <over>Station2</over>
    <over>Station3</over>
    <destination>Padaborn</destination>
  </rdf:Description>
</rdf:RDF>

然后您可以在 SPARQL 查询中只使用 一个 可选:

prefix : <urn:train:>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>

select * where {
  ?train :name ?name ;
         :description ?description ;
         :arrival ?arrival ;
         :departure ?departure ;
         :destination ?destination .
  optional {
    ?train :over ?over
  }
}
--------------------------------------------------------------------------------------------------------------------------------------------
| train   | name   | description  | arrival                              | departure                            | destination | over       |
============================================================================================================================================
| :train1 | "RE 1" | "Platform 1" | "2015-04-14T18:00:40Z"^^xsd:dateTime | "2015-04-14T18:02:40Z"^^xsd:dateTime | "Padaborn"  | "Station3" |
| :train1 | "RE 1" | "Platform 1" | "2015-04-14T18:00:40Z"^^xsd:dateTime | "2015-04-14T18:02:40Z"^^xsd:dateTime | "Padaborn"  | "Station2" |
| :train1 | "RE 1" | "Platform 1" | "2015-04-14T18:00:40Z"^^xsd:dateTime | "2015-04-14T18:02:40Z"^^xsd:dateTime | "Padaborn"  | "Station1" |
--------------------------------------------------------------------------------------------------------------------------------------------

您可能希望将它们放在一个列表中,因此您需要group_concat它们的值进行分组:

prefix : <urn:train:>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>

select ?train ?name ?description
       ?arrival ?departure
       ?destination
       (group_concat(?over) as ?overs)
where {
  ?train :name ?name ;
         :description ?description ;
         :arrival ?arrival ;
         :departure ?departure ;
         :destination ?destination .
  optional {
    ?train :over ?over
  }
}
group by ?train ?name ?description ?arrival ?departure ?destination
--------------------------------------------------------------------------------------------------------------------------------------------------------------
| train   | name   | description  | arrival                              | departure                            | destination | overs                        |
==============================================================================================================================================================
| :train1 | "RE 1" | "Platform 1" | "2015-04-14T18:00:40Z"^^xsd:dateTime | "2015-04-14T18:02:40Z"^^xsd:dateTime | "Padaborn"  | "Station3 Station2 Station1" |
--------------------------------------------------------------------------------------------------------------------------------------------------------------

如果顺序很重要

如果顺序更重要,那么您需要以某种方式保留它。您可以使用不同的属性来执行此操作,也可以使用具有列表值的属性(或其他一些支持排序的结构化数据)。

具有多个属性

使用 over1、over2、over3 属性的解决方案实际上可以仅使用一种可选模式来实现,因为您可以使用变量代替属性,然后过滤该属性的值。只需检查其 URI 是否以正确的前缀开头,包括

@prefix : <urn:train:>.
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.

:train1
  :name "RE 1" ;
  :description "Platform 1" ;
  :arrival "2015-04-14T18:00:40Z"^^xsd:dateTime ;
  :departure "2015-04-14T18:02:40Z"^^xsd:dateTime ;
  :over1 "Station1" ;
  :over2 "Station2" ;
  :over3 "Station3" ;
  :destination "Padaborn" .
<rdf:RDF
    xmlns="urn:train:"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema#">
  <rdf:Description rdf:about="urn:train:train1">
    <name>RE 1</name>
    <description>Platform 1</description>
    <arrival rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime"
    >2015-04-14T18:00:40Z</arrival>
    <departure rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime"
    >2015-04-14T18:02:40Z</departure>
    <over1>Station1</over1>
    <over2>Station2</over2>
    <over3>Station3</over3>
    <destination>Padaborn</destination>
  </rdf:Description>
</rdf:RDF>
prefix : <urn:train:>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>

select * where {
  ?train :name ?name ;
         :description ?description ;
         :arrival ?arrival ;
         :departure ?departure ;
         :destination ?destination .
  optional {
    ?train ?overProp ?over .
    filter strstarts(str(?overProp),str(:over))
  }
}
order by ?overProp
-------------------------------------------------------------------------------------------------------------------------------------------------------
| train   | name   | description  | arrival                              | departure                            | destination | overProp | over       |
=======================================================================================================================================================
| :train1 | "RE 1" | "Platform 1" | "2015-04-14T18:00:40Z"^^xsd:dateTime | "2015-04-14T18:02:40Z"^^xsd:dateTime | "Padaborn"  | :over1   | "Station1" |
| :train1 | "RE 1" | "Platform 1" | "2015-04-14T18:00:40Z"^^xsd:dateTime | "2015-04-14T18:02:40Z"^^xsd:dateTime | "Padaborn"  | :over2   | "Station2" |
| :train1 | "RE 1" | "Platform 1" | "2015-04-14T18:00:40Z"^^xsd:dateTime | "2015-04-14T18:02:40Z"^^xsd:dateTime | "Padaborn"  | :over3   | "Station3" |
-------------------------------------------------------------------------------------------------------------------------------------------------------

当然,您可以使用 group by 以相同的方式组合此处的值。

只有一点结构

您也可以只使用一个属性,但值是具有一点结构的东西。例如,一个空白节点,它有一个站的值和它通过的索引:

@prefix : <urn:train:>.
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.

:train1
  :name "RE 1" ;
  :description "Platform 1" ;
  :arrival "2015-04-14T18:00:40Z"^^xsd:dateTime ;
  :departure "2015-04-14T18:02:40Z"^^xsd:dateTime ;
  :over [:station "Station1" ; :number 2 ] ,
        [:station "Station2" ; :number 3 ] ,
        [:station "Station3" ; :number 1 ] ;
  :destination "Padaborn" .
<rdf:RDF
    xmlns="urn:train:"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema#">
  <rdf:Description rdf:about="urn:train:train1">
    <name>RE 1</name>
    <description>Platform 1</description>
    <arrival rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime"
    >2015-04-14T18:00:40Z</arrival>
    <departure rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime"
    >2015-04-14T18:02:40Z</departure>
    <over rdf:parseType="Resource">
      <station>Station1</station>
      <number rdf:datatype="http://www.w3.org/2001/XMLSchema#integer"
      >2</number>
    </over>
    <over rdf:parseType="Resource">
      <station>Station2</station>
      <number rdf:datatype="http://www.w3.org/2001/XMLSchema#integer"
      >3</number>
    </over>
    <over rdf:parseType="Resource">
      <station>Station3</station>
      <number rdf:datatype="http://www.w3.org/2001/XMLSchema#integer"
      >1</number>
    </over>
    <destination>Padaborn</destination>
  </rdf:Description>
</rdf:RDF>
prefix : <urn:train:>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

select * where {
  ?train :name ?name ;
         :description ?description ;
         :arrival ?arrival ;
         :departure ?departure ;
         :destination ?destination .
  optional {
    ?train :over [ :station ?over ;
                   :number ?number ]
  }
}
-----------------------------------------------------------------------------------------------------------------------------------------------------
| train   | name   | description  | arrival                              | departure                            | destination | over       | number |
=====================================================================================================================================================
| :train1 | "RE 1" | "Platform 1" | "2015-04-14T18:00:40Z"^^xsd:dateTime | "2015-04-14T18:02:40Z"^^xsd:dateTime | "Padaborn"  | "Station3" | 1      |
| :train1 | "RE 1" | "Platform 1" | "2015-04-14T18:00:40Z"^^xsd:dateTime | "2015-04-14T18:02:40Z"^^xsd:dateTime | "Padaborn"  | "Station2" | 3      |
| :train1 | "RE 1" | "Platform 1" | "2015-04-14T18:00:40Z"^^xsd:dateTime | "2015-04-14T18:02:40Z"^^xsd:dateTime | "Padaborn"  | "Station1" | 2      |
-----------------------------------------------------------------------------------------------------------------------------------------------------

只有一个属性和一个列表

你也可以有一个单一的 over 属性,它的值是一个列表。这在 N3/Turtle 序列化中非常容易编写。它在 RDF/XML 中没有那么漂亮,但就像我在评论中所说的那样,如果您是手写的,最好使用人类可编写的语法,或者使用适当的 API 来编写它。在 SPARQL 中查询也不难。

@prefix : <urn:train:>.
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.

:train1
  :name "RE 1" ;
  :description "Platform 1" ;
  :arrival "2015-04-14T18:00:40Z"^^xsd:dateTime ;
  :departure "2015-04-14T18:02:40Z"^^xsd:dateTime ;
  :over ("Station1" "Station2" "Station3") ;
  :destination "Padaborn" .
<rdf:RDF
    xmlns="urn:train:"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema#">
  <rdf:Description rdf:about="urn:train:train1">
    <name>RE 1</name>
    <description>Platform 1</description>
    <arrival rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime"
    >2015-04-14T18:00:40Z</arrival>
    <departure rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime"
    >2015-04-14T18:02:40Z</departure>
    <over rdf:parseType="Resource">
      <rdf:first>Station1</rdf:first>
      <rdf:rest rdf:parseType="Resource">
        <rdf:first>Station2</rdf:first>
        <rdf:rest rdf:parseType="Resource">
          <rdf:first>Station3</rdf:first>
          <rdf:rest rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"/>
        </rdf:rest>
      </rdf:rest>
    </over>
    <destination>Padaborn</destination>
  </rdf:Description>
</rdf:RDF>
prefix : <urn:train:>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

select * where {
  ?train :name ?name ;
         :description ?description ;
         :arrival ?arrival ;
         :departure ?departure ;
         :destination ?destination .
  optional {
    ?train :over/(rdf:rest*/rdf:first) ?over
  }
}
--------------------------------------------------------------------------------------------------------------------------------------------
| train   | name   | description  | arrival                              | departure                            | destination | over       |
============================================================================================================================================
| :train1 | "RE 1" | "Platform 1" | "2015-04-14T18:00:40Z"^^xsd:dateTime | "2015-04-14T18:02:40Z"^^xsd:dateTime | "Padaborn"  | "Station1" |
| :train1 | "RE 1" | "Platform 1" | "2015-04-14T18:00:40Z"^^xsd:dateTime | "2015-04-14T18:02:40Z"^^xsd:dateTime | "Padaborn"  | "Station2" |
| :train1 | "RE 1" | "Platform 1" | "2015-04-14T18:00:40Z"^^xsd:dateTime | "2015-04-14T18:02:40Z"^^xsd:dateTime | "Padaborn"  | "Station3" |
--------------------------------------------------------------------------------------------------------------------------------------------

当然,您也可以在此处group bygroup_concat。使用基于列表的方法,您实际上也可以计算元素在列表中的位置。例如,请参阅我对 Is it possible to get the position of an element in an RDF Collection in SPARQL? 的回答。

【讨论】:

  • 这很容易成为我在这个网站上得到的最佳答案!非常感谢,你是我的英雄!
  • @MikeyB 顺便说一句,不久前有一个关于表示火车时刻表的问题。有没有可能是你提到的另一个人?
  • 这看起来不像是我团队中的一个人的作品。一定是巧合。对我来说可能仍然很有趣。也谢谢你
  • @MikeyB 不用担心;只是看起来很相似(火车线路的复杂表示),你提到的时间(在其他人之前已经设置的代码库上工作)让我想知道。那么,也许它们作为背景会很有趣。享受吧!
猜你喜欢
  • 2011-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-03
  • 2019-02-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多