redlander 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +59 -0
- data/Rakefile +5 -0
- data/ext/README +1 -0
- data/ext/extconf.rb +17 -0
- data/ext/redland-pre.i +6 -0
- data/ext/redland-types.i +9 -0
- data/ext/redland_wrap.c +8052 -0
- data/lib/redlander.rb +61 -0
- data/lib/redlander/error_container.rb +41 -0
- data/lib/redlander/model.rb +33 -0
- data/lib/redlander/model_proxy.rb +85 -0
- data/lib/redlander/node.rb +90 -0
- data/lib/redlander/parser.rb +92 -0
- data/lib/redlander/parser_proxy.rb +18 -0
- data/lib/redlander/serializer.rb +80 -0
- data/lib/redlander/statement.rb +153 -0
- data/lib/redlander/statement_iterator.rb +37 -0
- data/lib/redlander/storage.rb +79 -0
- data/lib/redlander/version.rb +3 -0
- data/spec/redlander/model_spec.rb +239 -0
- data/spec/redlander/node_spec.rb +85 -0
- data/spec/redlander/parser_spec.rb +96 -0
- data/spec/redlander/serializer_spec.rb +52 -0
- data/spec/redlander/statement_spec.rb +86 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +10 -0
- metadata +127 -0
data/lib/redlander.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__)) unless
|
2
|
+
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
|
+
|
4
|
+
require 'uri'
|
5
|
+
require 'xml_schema'
|
6
|
+
|
7
|
+
module Redlander
|
8
|
+
require 'redland'
|
9
|
+
require 'redlander/version'
|
10
|
+
|
11
|
+
class RedlandError < RuntimeError; end
|
12
|
+
|
13
|
+
class << self
|
14
|
+
|
15
|
+
def rdf_world
|
16
|
+
unless @rdf_world
|
17
|
+
@rdf_world = Redland.librdf_new_world
|
18
|
+
raise RedlandError.new("Could not create a new RDF world") unless @rdf_world
|
19
|
+
ObjectSpace.define_finalizer(@rdf_world, proc { Redland.librdf_free_world(@rdf_world) })
|
20
|
+
Redland.librdf_world_open(@rdf_world)
|
21
|
+
end
|
22
|
+
@rdf_world
|
23
|
+
end
|
24
|
+
|
25
|
+
# Convert options hash into a string for librdf.
|
26
|
+
# What it does:
|
27
|
+
# 1) Convert boolean values into 'yes/no' values
|
28
|
+
# 2) Change underscores in key names into dashes ('dhar_ma' => 'dhar-ma')
|
29
|
+
# 3) Join all options as "key='value'" pairs in a comma-separated string
|
30
|
+
def to_rdf_options(options = {})
|
31
|
+
options.inject([]){|opts, option_pair|
|
32
|
+
key = option_pair[0].to_s.gsub(/_/, '-')
|
33
|
+
value = if [TrueClass, FalseClass].include?(option_pair[1].class)
|
34
|
+
option_pair[1] ? 'yes' : 'no'
|
35
|
+
else
|
36
|
+
option_pair[1]
|
37
|
+
end
|
38
|
+
opts << "#{key}='#{value}'"
|
39
|
+
}.join(',')
|
40
|
+
end
|
41
|
+
|
42
|
+
# Helper method to create an instance of rdfuri.
|
43
|
+
# For internal use only!
|
44
|
+
def to_rdf_uri(uri)
|
45
|
+
return nil if uri.nil?
|
46
|
+
uri = uri.is_a?(URI) ? uri.to_s : uri
|
47
|
+
rdf_uri = Redland.librdf_new_uri(rdf_world, uri)
|
48
|
+
raise RedlandError.new("Failed to create URI from '#{uri}'") unless rdf_uri
|
49
|
+
ObjectSpace.define_finalizer(rdf_uri, proc { Redland.librdf_free_uri(rdf_uri) })
|
50
|
+
rdf_uri
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
require 'redlander/error_container'
|
56
|
+
require 'redlander/statement_iterator'
|
57
|
+
require 'redlander/parser'
|
58
|
+
require 'redlander/serializer'
|
59
|
+
require 'redlander/model'
|
60
|
+
require 'redlander/node'
|
61
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module ErrorContainer
|
2
|
+
|
3
|
+
class Errors
|
4
|
+
include Enumerable
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@container = []
|
8
|
+
end
|
9
|
+
|
10
|
+
def add(error_message)
|
11
|
+
if @container.include?(error_message)
|
12
|
+
@container
|
13
|
+
else
|
14
|
+
@container << error_message
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def each
|
19
|
+
@container.each do |err|
|
20
|
+
yield err
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def empty?
|
25
|
+
@container.empty?
|
26
|
+
end
|
27
|
+
|
28
|
+
def clear
|
29
|
+
@container.clear
|
30
|
+
end
|
31
|
+
|
32
|
+
def size
|
33
|
+
@container.size
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def errors
|
38
|
+
@errors ||= Errors.new
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'redlander/storage'
|
2
|
+
require 'redlander/model_proxy'
|
3
|
+
|
4
|
+
module Redlander
|
5
|
+
|
6
|
+
class Model
|
7
|
+
|
8
|
+
include Redlander::ParsingInstanceMethods
|
9
|
+
include Redlander::SerializingInstanceMethods
|
10
|
+
|
11
|
+
attr_reader :rdf_model
|
12
|
+
|
13
|
+
# Create a new RDF model.
|
14
|
+
# For explanation of options, read Storage.initialize_storage
|
15
|
+
def initialize(options = {})
|
16
|
+
@rdf_storage = Storage.initialize_storage(options)
|
17
|
+
|
18
|
+
@rdf_model = Redland.librdf_new_model(Redlander.rdf_world, @rdf_storage, "")
|
19
|
+
raise RedlandError.new("Failed to create a new model") unless @rdf_model
|
20
|
+
ObjectSpace.define_finalizer(@rdf_model, proc { Redland.librdf_free_model(@rdf_model) })
|
21
|
+
end
|
22
|
+
|
23
|
+
# Statements contained in the model.
|
24
|
+
#
|
25
|
+
# Similar to Ruby on Rails, a proxy object is actually returned,
|
26
|
+
# which delegates methods to Statement class.
|
27
|
+
def statements
|
28
|
+
ModelProxy.new(self)
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'redlander/statement'
|
2
|
+
|
3
|
+
module Redlander
|
4
|
+
|
5
|
+
class ModelProxy
|
6
|
+
|
7
|
+
include StatementIterator
|
8
|
+
|
9
|
+
def initialize(model, rdf_stream = nil)
|
10
|
+
@model = model
|
11
|
+
@rdf_stream = if rdf_stream
|
12
|
+
rdf_stream
|
13
|
+
else
|
14
|
+
Redland.librdf_model_as_stream(@model.rdf_model)
|
15
|
+
end
|
16
|
+
raise RedlandError.new("Failed to create a new stream") unless @rdf_stream
|
17
|
+
ObjectSpace.define_finalizer(@rdf_stream, proc { Redland.librdf_free_stream(@rdf_stream) })
|
18
|
+
end
|
19
|
+
|
20
|
+
# Add a statement to the model.
|
21
|
+
# It must be a complete statement - all of subject, predicate, object parts must be present.
|
22
|
+
# Only statements that are legal RDF can be added.
|
23
|
+
# If the statement already exists in the model, it is not added.
|
24
|
+
#
|
25
|
+
# Returns true on success or false on failure.
|
26
|
+
def add(statement)
|
27
|
+
statement.model = @model
|
28
|
+
end
|
29
|
+
|
30
|
+
# Create a statement and add it to the model.
|
31
|
+
#
|
32
|
+
# Options are:
|
33
|
+
# :subject, :predicate, :object,
|
34
|
+
# (see Statement.new for option explanations).
|
35
|
+
#
|
36
|
+
# Returns an instance of Statement on success,
|
37
|
+
# or nil if the statement could not be added.
|
38
|
+
def create(options = {})
|
39
|
+
statement = Statement.new(options)
|
40
|
+
add(statement) && statement
|
41
|
+
end
|
42
|
+
|
43
|
+
def empty?
|
44
|
+
size.zero?
|
45
|
+
end
|
46
|
+
|
47
|
+
def size
|
48
|
+
s = Redland.librdf_model_size(@model.rdf_model)
|
49
|
+
if s < 0
|
50
|
+
raise RedlandError.new("Attempt to get size when using non-countable storage")
|
51
|
+
else
|
52
|
+
s
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Find statements satisfying the given criteria.
|
57
|
+
# Scope can be:
|
58
|
+
# :all
|
59
|
+
# :first
|
60
|
+
def find(scope, options = {})
|
61
|
+
statement = Statement.new(options)
|
62
|
+
rdf_stream = Redland.librdf_model_find_statements(@model.rdf_model, statement.rdf_statement)
|
63
|
+
proxy = self.class.new(@model, rdf_stream)
|
64
|
+
|
65
|
+
case scope
|
66
|
+
when :first
|
67
|
+
proxy.first
|
68
|
+
when :all
|
69
|
+
if block_given?
|
70
|
+
proxy.each
|
71
|
+
else
|
72
|
+
proxy
|
73
|
+
end
|
74
|
+
else
|
75
|
+
raise RedlandError.new("Invalid search scope '#{scope}' specified.")
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def all(options = {})
|
80
|
+
find(:all, options)
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module Redlander
|
2
|
+
|
3
|
+
class Node
|
4
|
+
|
5
|
+
attr_reader :rdf_node
|
6
|
+
|
7
|
+
# Create a RDF node.
|
8
|
+
# Argument can be:
|
9
|
+
# - an instance of URI - to create a RDF "resource",
|
10
|
+
# - an instance of Node - to create a copy of the node,
|
11
|
+
# - nil (or absent) - to create a "blank" node,
|
12
|
+
# - any other Ruby object, which can be coerced into a literal.
|
13
|
+
# If nothing else, a RedlandError is thrown.
|
14
|
+
#
|
15
|
+
# Note, that you cannot create a resource node from an URI string,
|
16
|
+
# it must be an instance of URI. Otherwise it is treated as a string literal.
|
17
|
+
def initialize(arg = nil)
|
18
|
+
@rdf_node = if arg.nil?
|
19
|
+
Redland.librdf_new_node_from_blank_identifier(Redlander.rdf_world, nil)
|
20
|
+
elsif arg.is_a?(URI)
|
21
|
+
Redland.librdf_new_node_from_uri_string(Redlander.rdf_world, arg.to_s)
|
22
|
+
elsif arg.is_a?(SWIG::TYPE_p_librdf_node_s)
|
23
|
+
# A special case, where you can pass an instance of SWIG::TYPE_p_librdf_node_s
|
24
|
+
# in order to create a Node from an internal RDF node representation.
|
25
|
+
arg
|
26
|
+
elsif arg.is_a?(Node)
|
27
|
+
Redland.librdf_new_node_from_node(arg.rdf_node)
|
28
|
+
else
|
29
|
+
value = arg.respond_to?(:xmlschema) ? arg.xmlschema : arg.to_s
|
30
|
+
datatype = Redlander.to_rdf_uri(XmlSchema.datatype_of(arg))
|
31
|
+
Redland.librdf_new_node_from_typed_literal(Redlander.rdf_world, value, nil, datatype)
|
32
|
+
end
|
33
|
+
|
34
|
+
raise RedlandError.new("Failed to create a new node") unless @rdf_node
|
35
|
+
ObjectSpace.define_finalizer(@rdf_node, proc { Redland.librdf_free_node(@rdf_node) })
|
36
|
+
end
|
37
|
+
|
38
|
+
def resource?
|
39
|
+
!Redland.librdf_node_is_resource(@rdf_node).zero?
|
40
|
+
end
|
41
|
+
|
42
|
+
# Return true if node is a literal.
|
43
|
+
def literal?
|
44
|
+
!Redland.librdf_node_is_literal(@rdf_node).zero?
|
45
|
+
end
|
46
|
+
|
47
|
+
# Return true if node is a blank node.
|
48
|
+
def blank?
|
49
|
+
!Redland.librdf_node_is_blank(@rdf_node).zero?
|
50
|
+
end
|
51
|
+
|
52
|
+
# Return the datatype URI of the node.
|
53
|
+
# Returns nil if the node is not a literal, or has no datatype URI.
|
54
|
+
def datatype
|
55
|
+
if rdf_uri = Redland.librdf_node_get_literal_value_datatype_uri(@rdf_node)
|
56
|
+
ObjectSpace.define_finalizer(rdf_uri, proc { Redland.librdf_free_uri(rdf_uri) })
|
57
|
+
Redland.librdf_uri_to_string(rdf_uri)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Equivalency. Only works for comparing two Nodes.
|
62
|
+
def eql?(other_node)
|
63
|
+
!Redland.librdf_node_equals(@rdf_node, other_node.rdf_node).zero?
|
64
|
+
end
|
65
|
+
alias_method :==, :eql?
|
66
|
+
|
67
|
+
def hash
|
68
|
+
self.class.hash + to_s.hash
|
69
|
+
end
|
70
|
+
|
71
|
+
# Convert this node to a string (with a datatype suffix).
|
72
|
+
def to_s
|
73
|
+
Redland.librdf_node_to_string(@rdf_node)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Value of the literal node as a Ruby object instance.
|
77
|
+
def value
|
78
|
+
if resource?
|
79
|
+
if rdf_uri = Redland.librdf_node_get_uri(@rdf_node)
|
80
|
+
ObjectSpace.define_finalizer(rdf_uri, proc { Redland.librdf_free_uri(rdf_uri) })
|
81
|
+
URI.parse(Redland.librdf_uri_to_string(rdf_uri))
|
82
|
+
end
|
83
|
+
else
|
84
|
+
XmlSchema.instantiate(to_s)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'redlander/parser_proxy'
|
2
|
+
|
3
|
+
module Redlander
|
4
|
+
|
5
|
+
class Parser
|
6
|
+
|
7
|
+
attr_reader :rdf_parser
|
8
|
+
|
9
|
+
# Create a new parser.
|
10
|
+
# Name can be either of [:rdfxml, :ntriples, :turtle],
|
11
|
+
# or nil, which defaults to :rdfxml.
|
12
|
+
#
|
13
|
+
# TODO: Only a small subset of parsers is implemented,
|
14
|
+
# because the rest seem to be very buggy.
|
15
|
+
def initialize(name = :rdfxml)
|
16
|
+
# name, mime-type and syntax uri can all be nil, which defaults to :rdfxml parser
|
17
|
+
@rdf_parser = Redland.librdf_new_parser(Redlander.rdf_world, name.to_s, nil, nil)
|
18
|
+
raise RedlandError.new("Failed to create a new parser") unless @rdf_parser
|
19
|
+
ObjectSpace.define_finalizer(@rdf_parser, proc { Redland.librdf_free_parser(@rdf_parser) })
|
20
|
+
end
|
21
|
+
|
22
|
+
# Parse the content (String) into the model.
|
23
|
+
#
|
24
|
+
# Options are:
|
25
|
+
# :base_uri base URI (String or URI)
|
26
|
+
#
|
27
|
+
# Returns true on success, or false.
|
28
|
+
def from_string(model, content, options = {})
|
29
|
+
# FIXME: A bug (?) in Redland breaks NTriples parser if its input is not terminated with "\n"
|
30
|
+
content.concat("\n") unless content.end_with?("\n")
|
31
|
+
Redland.librdf_parser_parse_string_into_model(@rdf_parser, content, Redlander.to_rdf_uri(options[:base_uri]), model.rdf_model).zero?
|
32
|
+
end
|
33
|
+
|
34
|
+
# Parse the content from URI into the model.
|
35
|
+
# (It is possible to use "file:" schema for local files).
|
36
|
+
#
|
37
|
+
# Options are:
|
38
|
+
# :base_uri base URI (String or URI)
|
39
|
+
#
|
40
|
+
# Returns true on success, or false.
|
41
|
+
def from_uri(model, uri, options = {})
|
42
|
+
uri = URI.parse(uri)
|
43
|
+
uri = URI.parse("file://#{File.expand_path(uri.to_s)}") if uri.scheme.nil?
|
44
|
+
Redland.librdf_parser_parse_into_model(@rdf_parser, Redlander.to_rdf_uri(uri), Redlander.to_rdf_uri(options[:base_uri]), model.rdf_model).zero?
|
45
|
+
end
|
46
|
+
alias_method :from_file, :from_uri
|
47
|
+
|
48
|
+
def statements(content, options = {})
|
49
|
+
# BUG: Parser accumulates data from consequent runs??? WTF, Redland?!
|
50
|
+
# When parsing a series of files, parser reported a duplicate entry,
|
51
|
+
# then seemed to have stopped yielding statements at all.
|
52
|
+
|
53
|
+
# FIXME: A bug (?) in Redland breaks NTriples parser if its input is not terminated with "\n"
|
54
|
+
content.concat("\n") unless content.end_with?("\n")
|
55
|
+
ParserProxy.new(self, content, options)
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
module ParsingInstanceMethods
|
62
|
+
|
63
|
+
def from_rdfxml(content, options = {})
|
64
|
+
parser = Parser.new(:rdfxml)
|
65
|
+
parser.from_string(self, content, options)
|
66
|
+
end
|
67
|
+
|
68
|
+
def from_ntriples(content, options = {})
|
69
|
+
parser = Parser.new(:ntriples)
|
70
|
+
parser.from_string(self, content, options)
|
71
|
+
end
|
72
|
+
|
73
|
+
def from_turtle(content, options = {})
|
74
|
+
parser = Parser.new(:turtle)
|
75
|
+
parser.from_string(self, content, options)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Load the model from an URI content.
|
79
|
+
#
|
80
|
+
# Options are:
|
81
|
+
# :format - content format [:rdfxml (default), :ntriples, :turtle]
|
82
|
+
# :base_uri - base URI
|
83
|
+
def from_uri(uri, options = {})
|
84
|
+
parser_options = options.dup
|
85
|
+
parser = Parser.new(parser_options.delete(:format) || :rdfxml)
|
86
|
+
parser.from_uri(self, uri, parser_options)
|
87
|
+
end
|
88
|
+
alias_method :from_file, :from_uri
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'redlander/statement'
|
2
|
+
|
3
|
+
module Redlander
|
4
|
+
|
5
|
+
class ParserProxy
|
6
|
+
|
7
|
+
include StatementIterator
|
8
|
+
|
9
|
+
def initialize(parser, content, options = {})
|
10
|
+
@model = nil # the yielded statements will not be bound to a model
|
11
|
+
@rdf_stream = Redland.librdf_parser_parse_string_as_stream(parser.rdf_parser, content, Redlander.to_rdf_uri(options[:base_uri]))
|
12
|
+
raise RedlandError.new("Failed to create a new stream") unless @rdf_stream
|
13
|
+
ObjectSpace.define_finalizer(@rdf_stream, proc { Redland.librdf_free_stream(@rdf_stream) })
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module Redlander
|
2
|
+
|
3
|
+
class Serializer
|
4
|
+
|
5
|
+
# Create a new serializer.
|
6
|
+
# Name can be either of [:rdfxml, :ntriples, :turtle, :json, :dot],
|
7
|
+
# or nil, which defaults to :rdfxml.
|
8
|
+
#
|
9
|
+
# TODO: Only a small subset of parsers is implemented,
|
10
|
+
# because the rest seem to be very buggy.
|
11
|
+
def initialize(name = :rdfxml)
|
12
|
+
@rdf_serializer = Redland.librdf_new_serializer(Redlander.rdf_world, name.to_s, nil, nil)
|
13
|
+
raise RedlandError.new("Failed to create a new serializer") unless @rdf_serializer
|
14
|
+
ObjectSpace.define_finalizer(@rdf_serializer, proc { Redland.librdf_free_serializer(@rdf_serializer) })
|
15
|
+
end
|
16
|
+
|
17
|
+
# Serialize a model into a string.
|
18
|
+
#
|
19
|
+
# Options are:
|
20
|
+
# :base_uri base URI (String or URI)
|
21
|
+
def to_string(model, options = {})
|
22
|
+
Redland.librdf_serializer_serialize_model_to_string(@rdf_serializer, Redlander.to_rdf_uri(options[:base_uri]), model.rdf_model)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Serializes a model and stores it in a file
|
26
|
+
# filename - the name of the file to serialize to
|
27
|
+
# model - model instance
|
28
|
+
#
|
29
|
+
# Options are:
|
30
|
+
# :base_uri base URI (String or URI)
|
31
|
+
#
|
32
|
+
# Returns true on success, or false.
|
33
|
+
def to_file(model, filename, options = {})
|
34
|
+
Redland.librdf_serializer_serialize_model_to_file(@rdf_serializer, filename, Redlander.to_rdf_uri(options[:base_uri]), model.rdf_model).zero?
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
module SerializingInstanceMethods
|
41
|
+
|
42
|
+
def to_rdfxml(options = {})
|
43
|
+
serializer = Serializer.new(:rdfxml)
|
44
|
+
serializer.to_string(self, options)
|
45
|
+
end
|
46
|
+
|
47
|
+
def to_ntriples(options = {})
|
48
|
+
serializer = Serializer.new(:ntriples)
|
49
|
+
serializer.to_string(self, options)
|
50
|
+
end
|
51
|
+
|
52
|
+
def to_turtle(options = {})
|
53
|
+
serializer = Serializer.new(:turtle)
|
54
|
+
serializer.to_string(self, options)
|
55
|
+
end
|
56
|
+
|
57
|
+
def to_json(options = {})
|
58
|
+
serializer = Serializer.new(:json)
|
59
|
+
serializer.to_string(self, options)
|
60
|
+
end
|
61
|
+
|
62
|
+
def to_dot(options = {})
|
63
|
+
serializer = Serializer.new(:dot)
|
64
|
+
serializer.to_string(self, options)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Serialize the model into a file.
|
68
|
+
#
|
69
|
+
# Options are:
|
70
|
+
# :format - output format [:rdfxml (default), :ntriples, :turtle, :json, :dot]
|
71
|
+
# :base_uri - base URI
|
72
|
+
def to_file(filename, options = {})
|
73
|
+
serializer_options = options.dup
|
74
|
+
serializer = Serializer.new(serializer_options.delete(:format) || :rdfxml)
|
75
|
+
serializer.to_file(self, filename, serializer_options)
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|