我正在接收xml序列化的RDF(作为XMP媒体描述的一部分,如果是相关的),并在Ruby中进行处理。我正在尝试使用rdf
gem,尽管很乐意看其他解决方案。
我已设法加载并查询最基本的数据,但在尝试为包含序列和包的项目构建查询时遇到困难。
示例XML RDF:
<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
<rdf:Description rdf:about='' xmlns:dc='http://purl.org/dc/elements/1.1/'>
<dc:date>
<rdf:Seq>
<rdf:li>2013-04-08</rdf:li>
</rdf:Seq>
</dc:date>
</rdf:Description>
</rdf:RDF>
我最好尝试整理查询:
require 'rdf'
require 'rdf/rdfxml'
require 'rdf/vocab/dc11'
graph = RDF::Graph.load( 'test.rdf' )
date_query = RDF::Query.new( :subject => { RDF::DC11.date => :date } )
results = date_query.execute(graph)
results.map { |result| { result.subject.to_s => result.date.inspect } }
=> [{"test.rdf"=>"#<RDF::Node:0x3fc186b3eef8(_:g70100421177080)>"}]
我的印象是我在此阶段的结果(“查询解决方案”?)是对rdf:Seq
容器的引用。但我迷失了如何进步。对于上面的例子,我希望最终得到一个数组["2013-04-08"]
。
当有没有rdf:Seq
和rdf:li
容器的传入数据时,我可以使用RDF::Query
提取我想要的字符串,以下是http://rdf.rubyforge.org/RDF/Query.html的示例 - 很遗憾我找不到任何更复杂的查询或Ruby中处理的RDF结构的例子。
编辑:此外,当我尝试找到与RDF::Node
对象一起使用的适当方法时,我看不出有任何方法可以探索它可能具有的任何进一步关系:
results[0].date.methods - Object.methods
=> [:original, :original=, :id, :id=, :node?, :anonymous?, :unlabeled?, :labeled?, :to_sym, :resource?, :constant?, :variable?, :between?, :graph?, :literal?, :statement?, :iri?, :uri?, :valid?, :invalid?, :validate!, :validate, :to_rdf, :inspect!, :type_error, :to_ntriples]
# None of the above leads AFAICS to more data in the graph
我知道如何在xpath中获取相同的数据(好吧,至少假设我们总是在序列化中获得相同的路径),但感觉它不是在这种情况下使用的最佳查询语言(这是我的备份计划,但是,如果结果太复杂,无法实现RDF查询解决方案)
答案 0 :(得分:3)
我认为你说“我在这个阶段的结果(”查询解决方案“?)是对rdf:Seq容器的引用”是正确的。 RDF / XML是一种非常糟糕的序列化格式,而是将数据视为图形。这是一张RDF照片:Bag。 RDF:Seq的工作方式相同,示例中的#students类似于您的情况下的#date。
因此,要获取日期文字,您需要在图表中进一步跳转一个节点。我不熟悉这个Ruby库的语法,但是类似于:
require 'rdf'
require 'rdf/rdfxml'
require 'rdf/vocab/dc11'
graph = RDF::Graph.load( 'test.rdf' )
date_query = RDF::Query.new({
:yourThing => {
RDF::DC11.date => :dateSeq
},
:dateSeq => {
RDF.type => RDF.Seq,
RDF._1 => :dateLiteral
}
})
date_query.execute(graph).each do |solution|
puts "date=#{solution.dateLiteral}"
end
当然,如果您希望Seq实际上包含多个日期(否则拥有Seq没有意义),您必须将它们与RDF._1 => :dateLiteral1
,RDF._2 => :dateLiteral2
匹配, RDF._3 => :dateLiteral3
等。
或者对于更通用的解决方案,将dateSeq上的所有属性和对象与:
匹配:dateSeq => {
:property => :dateLiteral
}
然后过滤掉:property
最终为RDF:type
的情况,而:dateLiteral
实际上不是日期而是RDF:Seq
。也许图书馆还有一种特殊的方法来获取所有Seq的内容。