当前位置: 动力学知识库 > 问答 > 编程问答 >

Ruby RDF query - extracting simple data from Seq and Bag items

问题描述:

I am receiving xml-serialised RDF (as part of XMP media descriptions in case that is relevent), and processing in Ruby. I am trying to work with rdf gem, although happy to look at other solutions.

I have managed to load and query the most basic data, but am stuck when trying to build a query for items which contain sequences and bags.

Example 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>

My best attempt at putting together a query:

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)>"}]

I get the impression that my results at this stage ("query solutions"?) are a reference to the rdf:Seq container. But I am lost as to how to progress. For the example above, I'd expect to end up, eventually, with an array ["2013-04-08"].

When there is incoming data without the rdf:Seq and rdf:li containers, I am able to extract the strings I want using RDF::Query, following examples at http://rdf.rubyforge.org/RDF/Query.html - unfortunately I cannot find any examples of more complex queries or RDF structures processed in Ruby.

Edit: In addition, when I try to find appropriate methods to use with the RDF::Node object, I cannot see any way to explore any further relations it may have:

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

I know how to get the same data in xpath (well, at least provided we always get the same paths in the serialisation), but feel it is not the best query language to use in this case (it's my backup plan, however, if it turns out too complex to implement an RDF-query solution)

网友答案:

I think you're correct when saying "my results at this stage ("query solutions"?) are a reference to the rdf:Seq container". RDF/XML is a really horrible serialisation format, instead think of the data as a graph. Here a picture of an RDF:Bag. RDF:Seq works the same and the #students in the example is analogous to the #date in your case.

So to get to the date literal, you need to hop one node further in the graph. I'm not familiar with the syntax of this Ruby library, but something like:

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

Of course, if you expect the Seq to actually to contain multiple dates (otherwise it wouldn't make sense to have a Seq), you will have to match them with RDF._1 => :dateLiteral1, RDF._2 => :dateLiteral2, RDF._3 => :dateLiteral3 etc.

Or for a more generic solution, match all the properties and objects on the dateSeq with:

:dateSeq => {
    :property => :dateLiteral
}

and then filter out the case where :property ends up being RDF:type while :dateLiteral isn't actually the date but RDF:Seq. Maybe the library has also a special method to get all the Seq's contents.

分享给朋友:
您可能感兴趣的文章:
随机阅读: