Class: RDF::TriG::Writer

Inherits:
RDF::Turtle::Writer
  • Object
show all
Includes:
StreamingWriter
Defined in:
lib/rdf/trig/writer.rb

Overview

A TriG serialiser

Note that the natural interface is to write a whole repository at a time. Writing statements or Triples will create a repository to add them to and then serialize the repository.

The writer will add prefix definitions, and use them for creating @prefix definitions, and minting QNames

Examples:

Obtaining a TriG writer class

RDF::Writer.for(:trig)         #=> RDF::TriG::Writer
RDF::Writer.for("etc/test.trig")
RDF::Writer.for(:file_name      => "etc/test.trig")
RDF::Writer.for(file_extension: "trig")
RDF::Writer.for(:content_type   => "application/trig")

Serializing RDF repo into an TriG file

RDF::TriG::Writer.open("etc/test.trig") do |writer|
  writer << repo
end

Serializing RDF statements into an TriG file

RDF::TriG::Writer.open("etc/test.trig") do |writer|
  repo.each_statement do |statement|
    writer << statement
  end
end

Serializing RDF statements into an TriG string

RDF::TriG::Writer.buffer do |writer|
  repo.each_statement do |statement|
    writer << statement
  end
end

Serializing RDF statements to a string in streaming mode

RDF::TriG::Writer.buffer(stream: true) do |writer|
  repo.each_statement do |statement|
    writer << statement
  end
end

Creating @base and @prefix definitions in output

RDF::TriG::Writer.buffer(base_uri: "http://example.com/", prefixes: {
    nil => "http://example.com/ns#",
    foaf: "http://xmlns.com/foaf/0.1/"}
) do |writer|
  repo.each_statement do |statement|
    writer << statement
  end
end

Author:

Instance Method Summary collapse

Methods included from StreamingWriter

#stream_epilogue, #stream_statement

Constructor Details

#initialize(output = $stdout, **options) {|writer| ... } ⇒ Writer

Initializes the TriG writer instance.

Parameters:

  • output (IO, File) (defaults to: $stdout)

    the output stream

  • options (Hash{Symbol => Object})

    any additional options

Options Hash (**options):

  • :encoding (Encoding) — default: Encoding::UTF_8

    the encoding to use on the output stream (Ruby 1.9+)

  • :canonicalize (Boolean) — default: false

    whether to canonicalize literals when serializing

  • :prefixes (Hash) — default: Hash.new

    the prefix mappings to use (not supported by all writers)

  • :base_uri (#to_s) — default: nil

    the base URI to use when constructing relative URIs

  • :max_depth (Integer) — default: 3

    Maximum depth for recursively defining resources, defaults to 3

  • :standard_prefixes (Boolean) — default: false

    Add standard prefixes to @prefixes, if necessary.

  • :stream (Boolean) — default: false

    Do not attempt to optimize graph presentation, suitable for streaming large repositories.

  • :default_namespace (String) — default: nil

    URI to use as default namespace, same as prefixes\[nil\]

Yields:

  • (writer)

    self

  • (writer)

Yield Parameters:

  • writer (RDF::Writer)
  • writer (RDF::Writer)

Yield Returns:

  • (void)


90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/rdf/trig/writer.rb', line 90

def initialize(output = $stdout, **options, &block)
  super do
    # Set both @repo and @graph to a new repository.
    @repo = @graph = RDF::Repository.new
    if block_given?
      case block.arity
        when 0 then instance_eval(&block)
        else block.call(self)
      end
    end
  end
end

Instance Method Details

#blankNodePropertyList?(resource, position) ⇒ Boolean (protected)

Add additional constraint that the resource must be in a single graph and must not be a graph name

Returns:

  • (Boolean)


194
195
196
# File 'lib/rdf/trig/writer.rb', line 194

def blankNodePropertyList?(resource, position)
  super && resource_in_single_graph?(resource) && !@graph_names.include?(resource)
end

#order_graphsObject (protected)

Order graphs for output



205
206
207
208
209
210
211
212
213
# File 'lib/rdf/trig/writer.rb', line 205

def order_graphs
  log_debug("order_graphs") {@repo.graph_names.to_a.inspect}
  graph_names = @repo.graph_names.to_a.sort
  
  # include default graph, if necessary
  graph_names.unshift(nil) unless @repo.query({graph_name: false}).to_a.empty?
  
  graph_names
end

#preprocess_statement(statement) ⇒ Object (protected)

Perform any statement preprocessing required. This is used to perform reference counts and determine required prefixes.

Parameters:

  • statement (Statement)


218
219
220
221
# File 'lib/rdf/trig/writer.rb', line 218

def preprocess_statement(statement)
  super
  get_pname(statement.graph_name) if statement.has_graph?
end

#resource_in_single_graph?(resource) ⇒ Boolean (protected)

Returns:

  • (Boolean)


198
199
200
201
202
# File 'lib/rdf/trig/writer.rb', line 198

def resource_in_single_graph?(resource)
  graph_names = @repo.query({subject: resource}).map(&:graph_name)
  graph_names += @repo.query({object: resource}).map(&:graph_name)
  graph_names.uniq.length <= 1
end

#write_epilogue

This method returns an undefined value.

Outputs the TriG representation of all stored triples.

Raises:

  • (RDF::WriterError)

See Also:

  • #write_triple


136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/rdf/trig/writer.rb', line 136

def write_epilogue
  case
  when @options[:stream]
    stream_epilogue
  else
    @max_depth = @options[:max_depth] || 3
    @base_uri = RDF::URI(@options[:base_uri])

    reset

    log_debug {"serialize: repo: #{@repo.size}"}

    preprocess
    start_document

    @graph_names = order_graphs
    @graph_names.each do |graph_name|
      log_depth do
        log_debug {"graph_name: #{graph_name.inspect}"}
        reset
        @options[:log_depth] = graph_name ? 1 : 0

        if graph_name
          @output.write("\n#{format_term(graph_name)} {")
        end

        # Restrict view to the particular graph
        @graph = @repo.project_graph(graph_name)

        # Pre-process statements again, but in the specified graph
        @graph.each {|st| preprocess_statement(st)}

        # Remove lists that are referenced and have non-list properties,
        # or are present in more than one graph, or have elements
        # that are present in more than one graph;
        # these are legal, but can't be serialized as lists
        @lists.reject! do |node, list|
          ref_count(node) > 0 && prop_count(node) > 0 ||
          list.subjects.any? {|elt| !resource_in_single_graph?(elt)}
        end

        order_subjects.each do |subject|
          unless is_done?(subject)
            statement(subject)
          end
        end

        @output.puts("}") if graph_name
      end
    end
  end
  raise RDF::WriterError, "Errors found during processing" if log_statistics[:error]
end

#write_prologue

This method returns an undefined value.

Write out declarations



122
123
124
125
126
127
128
129
# File 'lib/rdf/trig/writer.rb', line 122

def write_prologue
  case
  when @options[:stream]
    stream_prologue
  else
    super
  end
end

#write_quad(subject, predicate, object, graph_name)

This method returns an undefined value.

Adds a triple to be serialized

Parameters:

  • subject (RDF::Resource)
  • predicate (RDF::URI)
  • object (RDF::Value)
  • graph_name (RDF::Resource)


110
111
112
113
114
115
116
117
# File 'lib/rdf/trig/writer.rb', line 110

def write_quad(subject, predicate, object, graph_name)
  statement = RDF::Statement.new(subject, predicate, object, graph_name: graph_name)
  if @options[:stream]
    stream_statement(statement)
  else
    @graph.insert(statement)
  end
end