module SPARQL::Results

Generate SPARQL Results as Boolean, XML or JSON

This module is a mixin for RDF::Query::Solutions

Constants

MIME_TYPES

Public Instance Methods

to_csv(bnode_map: {}) click to toggle source

Generate Solutions as CSV @return [String] @see www.w3.org/TR/2013/REC-sparql11-results-csv-tsv-20130321/

# File lib/sparql/results.rb, line 143
def to_csv(bnode_map: {})
  require 'csv' unless defined?(::CSV)
  bnode_gen = "_:a"
  CSV.generate(row_sep: "\r\n") do |csv|
    csv << variable_names.to_a
    self.each do |solution|
      csv << variable_names.map do |n|
        case term = solution[n]
        when RDF::Node then bnode_map[term] ||=
          begin
            this = bnode_gen
            bnode_gen = bnode_gen.succ
            this
          end
        when RDF::Statement
          RDF::Query::Solutions(
            RDF::Query::Solution.new(subject: term.subject, predicate: term.predicate, object: term.object)
          ).to_csv(bnode_map: bnode_map).split.last.strip
        else
          solution[n].to_s.strip
        end
      end
    end
  end
end
to_html() click to toggle source

Generate Solutions as HTML @return [String] @see www.w3.org/TR/rdf-sparql-XMLres/

# File lib/sparql/results.rb, line 117
def to_html
  require 'builder' unless defined?(::Builder)
  
  xml = ::Builder::XmlMarkup.new(indent: 2)
  xml.table(class: "sparql") do
    xml.tbody do
      xml.tr do
        variable_names.each do |n|
          xml.th(n.to_s)
        end
      end
      self.each do |solution|
        xml.tr do
          variable_names.each do |n|
            xml.td(RDF::NTriples.serialize(solution[n]))
          end
        end
      end
    end
  end
end
to_json() click to toggle source

Generate Solutions as JSON @return [String] @see www.w3.org/TR/rdf-sparql-json-res/

# File lib/sparql/results.rb, line 18
def to_json
  require 'json' unless defined?(::JSON)

  format = ->(value) do
    case value
    when RDF::URI then {type: "uri", value: value.to_s }
    when RDF::Node then {type: "bnode", value: value.id }
    when RDF::Literal
      if value.datatype?
        {type: "typed-literal", datatype: value.datatype.to_s, value: value.to_s }
      elsif value.language?
        {type: "literal", "xml:lang" => value.language.to_s, value: value.to_s }
      else
        {type: "literal", value: value.to_s }
      end
    when RDF::Statement
      {
        type: 'triple',
        value: {
          subject: format.call(value.subject),
          predicate: format.call(value.predicate),
          object: format.call(value.object)
        }
      }
    end
  end

  bindings = self.map do |solution|
    variable_names.inject({}) do |memo, n|
      rep = format.call(solution[n])
      rep ? memo.merge(n => rep) : memo
    end
  end

  {
    :head     => { vars: variable_names },
    :results  => { bindings: bindings}
  }.to_json
end
to_tsv() click to toggle source

Generate Solutions as TSV @return [String] @see www.w3.org/TR/2013/REC-sparql11-results-csv-tsv-20130321/

# File lib/sparql/results.rb, line 172
def to_tsv
  require 'csv' unless defined?(::CSV)
  results = [
    variable_names.map {|v| "?#{v}"}.join("\t")
  ] + self.map do |solution|
    variable_names.map do |n|
      case term = solution[n]
      when RDF::Literal::Integer, RDF::Literal::Decimal, RDF::Literal::Double
        term.canonicalize.to_s
      when RDF::Statement
        emb_stmt = RDF::Query::Solutions(
          RDF::Query::Solution.new(subject: term.subject, predicate: term.predicate, object: term.object)
        ).to_tsv.split("\n").last.strip
        emb_stmt.gsub(/[\t\n\r]/, "\t" => '\t', "\n" => '\n', "\r" => '\r')
      when nil
        ""
      else
        RDF::NTriples.serialize(term).strip.gsub(/[\t\n\r]/, "\t" => '\t', "\n" => '\n', "\r" => '\r')
      end
    end.join("\t")
  end
  results.join("\n") + "\n"
end
to_xml() click to toggle source

Generate Solutions as XML @return [String] @see www.w3.org/TR/rdf-sparql-XMLres/

# File lib/sparql/results.rb, line 62
def to_xml
  require 'builder' unless defined?(::Builder)
  
  xml = ::Builder::XmlMarkup.new(indent: 2)
  xml.instruct!

  format = ->(s) do
    case s
    when RDF::URI
      xml.uri(s.to_s)
    when RDF::Node
      xml.bnode(s.id)
    when RDF::Literal
      if s.datatype?
        xml.literal(s.to_s, "datatype" => s.datatype.to_s)
      elsif s.language
        xml.literal(s.to_s, "xml:lang" => s.language.to_s)
      else
        xml.literal(s.to_s)
      end
    when RDF::Statement
      xml.triple do
        xml.subject {format.call(s.subject)}
        xml.predicate {format.call(s.predicate)}
        xml.object {format.call(s.object)}
      end
    end
  end

  xml.sparql(xmlns: "http://www.w3.org/2005/sparql-results#") do
    xml.head do
      variable_names.each do |n|
        xml.variable(name: n)
      end
    end
    xml.results do
      self.each do |solution|
        xml.result do
          variable_names.each do |n|
            s = solution[n]
            next unless s
            xml.binding(name: n) do
              format.call(s)
            end
          end
        end
      end
    end
  end
end