class JSON::LD::Writer

A JSON-LD parser in Ruby.

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

@example Obtaining a JSON-LD writer class

RDF::Writer.for(:jsonld)         #=> JSON::LD::Writer
RDF::Writer.for("etc/test.json")
RDF::Writer.for(:file_name      => "etc/test.json")
RDF::Writer.for(file_extension: "json")
RDF::Writer.for(:content_type   => "application/turtle")

@example Serializing RDF graph into an JSON-LD file

JSON::LD::Writer.open("etc/test.json") do |writer|
  writer << graph
end

@example Serializing RDF statements into an JSON-LD file

JSON::LD::Writer.open("etc/test.json") do |writer|
  graph.each_statement do |statement|
    writer << statement
  end
end

@example Serializing RDF statements into an JSON-LD string

JSON::LD::Writer.buffer do |writer|
  graph.each_statement do |statement|
    writer << statement
  end
end

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

@example Creating @@context prefix definitions in output

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

Select the :expand option to output JSON-LD in expanded form

@see www.w3.org/TR/json-ld11-api/ @see www.w3.org/TR/json-ld11-api/#the-normalization-algorithm @author [Gregg Kellogg](greggkellogg.net/)

Attributes

black_list[R]
white_list[R]
context[R]

@!attribute [r] context @return [Context] context used to load and administer contexts

graph[R]

@!attribute [r] graph @return [RDF::Graph] Graph of statements serialized

Public Class Methods

accept?(accept_params) { |accept_params| ... } click to toggle source

Use parameters from accept-params to determine if the parameters are acceptable to invoke this writer. The `accept_params` will subsequently be provided to the writer instance.

@param [Hash{Symbol => String}] accept_params @yield [accept_params] if a block is given, returns the result of evaluating that block @yieldparam [Hash{Symbol => String}] accept_params @return [Boolean] @see www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1

# File lib/json/ld/writer.rb, line 187
def accept?(accept_params)
  # Profiles that aren't specific IANA relations represent the URL
  # of a context or frame that may be subject to black- or white-listing
  profile = accept_params[:profile].to_s.split(/\s+/)

  if block_given?
    yield(accept_params)
  else
    true
  end
end
default_context() click to toggle source

Returns default context used for compacted profile without an explicit context URL @return [String]

# File lib/json/ld/writer.rb, line 202
def default_context; @default_context || JSON::LD::DEFAULT_CONTEXT; end
default_context=(url) click to toggle source

Sets default context used for compacted profile without an explicit context URL @param [String] url

# File lib/json/ld/writer.rb, line 207
def default_context=(url); @default_context = url; end
new(output = $stdout, **options, &block) click to toggle source

Initializes the JSON-LD writer instance.

@param [IO, File] output

the output stream

@param [Hash{Symbol => Object}] options

any additional options

@option options [Encoding] :encoding (Encoding::UTF_8)

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

@option options [Boolean] :canonicalize (false)

whether to canonicalize literals when serializing

@option options [Hash] :prefixes ({})

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

@option options [Boolean] :standard_prefixes (false)

Add standard prefixes to @prefixes, if necessary.

@option options [IO, Array, Hash, String, Context] :context ({})

context to use when serializing. Constructed context for native serialization.

@option options [IO, Array, Hash, String, Context] :frame ({})

frame to use when serializing.

@option options [Boolean] :unique_bnodes (false)

Use unique bnode identifiers, defaults to using the identifier which the node was originall initialized with (if any).

@option options [Boolean] :stream (false)

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

@yield [writer] `self` @yieldparam [RDF::Writer] writer @yieldreturn [void] @yield [writer] @yieldparam [RDF::Writer] writer

Calls superclass method
# File lib/json/ld/writer.rb, line 238
def initialize(output = $stdout, **options, &block)
  options[:base_uri] ||= options[:base] if options.key?(:base)
  options[:base] ||= options[:base_uri] if options.key?(:base_uri)
  super do
    @repo = RDF::Repository.new

    if block_given?
      case block.arity
        when 0 then instance_eval(&block)
        else block.call(self)
      end
    end
  end
end
options() click to toggle source

JSON-LD Writer options @see www.rubydoc.info/github/ruby-rdf/rdf/RDF/Writer#options-class_method

Calls superclass method
# File lib/json/ld/writer.rb, line 74
def self.options
  super + [
    RDF::CLI::Option.new(
      symbol: :compactArrays,
      datatype: TrueClass,
      default: true,
      control: :checkbox,
      on: ["--[no-]compact-arrays"],
      description: "Replaces arrays with just one element with that element during compaction. Default is `true` use --no-compact-arrays to disable.") {|arg| arg},
    RDF::CLI::Option.new(
      symbol: :compactToRelative,
      datatype: TrueClass,
      default: true,
      control: :checkbox,
      on: ["--[no-]compact-to-relative"],
      description: "Creates document relative IRIs when compacting, if `true`, otherwise leaves expanded. Default is `true` use --no-compact-to-relative to disable.") {|arg| arg},
    RDF::CLI::Option.new(
      symbol: :context,
      datatype: RDF::URI,
      control: :url2,
      on: ["--context CONTEXT"],
      description: "Context to use when compacting.") {|arg| RDF::URI(arg).absolute? ? RDF::URI(arg) : StringIO.new(File.read(arg))},
    RDF::CLI::Option.new(
      symbol: :embed,
      datatype: %w(@always @once @never),
      default: '@once',
      control: :select,
      on: ["--embed EMBED"],
      description: "How to embed matched objects (@once).") {|arg| RDF::URI(arg)},
    RDF::CLI::Option.new(
      symbol: :explicit,
      datatype: TrueClass,
      control: :checkbox,
      on: ["--[no-]explicit"],
      description: "Only include explicitly declared properties in output (false)") {|arg| arg},
    RDF::CLI::Option.new(
      symbol: :frame,
      datatype: RDF::URI,
      control: :url2,
      use: :required,
      on: ["--frame FRAME"],
      description: "Frame to use when serializing.") {|arg| RDF::URI(arg).absolute? ? RDF::URI(arg) : StringIO.new(File.read(arg))},
    RDF::CLI::Option.new(
      symbol: :lowercaseLanguage,
      datatype: TrueClass,
      control: :checkbox,
      on: ["--[no-]lowercase-language"],
      description: "By default, language tags are left as is. To normalize to lowercase, set this option to `true`."),
    RDF::CLI::Option.new(
      symbol: :omitDefault,
      datatype: TrueClass,
      control: :checkbox,
      on: ["--[no-]omitDefault"],
      description: "Omit missing properties from output (false)") {|arg| arg},
    RDF::CLI::Option.new(
      symbol: :ordered,
      datatype: TrueClass,
      control: :checkbox,
      on: ["--[no-]ordered"],
      description: "Order object member processing lexographically.") {|arg| arg},
    RDF::CLI::Option.new(
      symbol: :processingMode,
      datatype: %w(json-ld-1.0 json-ld-1.1),
      control: :radio,
      on: ["--processingMode MODE", %w(json-ld-1.0 json-ld-1.1)],
      description: "Set Processing Mode (json-ld-1.0 or json-ld-1.1)"),
    RDF::CLI::Option.new(
      symbol: :rdfDirection,
      datatype: %w(i18n-datatype compound-literal),
      default: 'null',
      control: :select,
      on: ["--rdf-direction DIR", %w(i18n-datatype compound-literal)],
      description: "How to serialize literal direction (i18n-datatype compound-literal)") {|arg| arg},
    RDF::CLI::Option.new(
      symbol: :requireAll,
      datatype: TrueClass,
      default: true,
      control: :checkbox,
      on: ["--[no-]require-all"],
      description: "Require all properties to match (true). Default is `true` use --no-require-all to disable.") {|arg| arg},
    RDF::CLI::Option.new(
      symbol: :stream,
      datatype: TrueClass,
      control: :checkbox,
      on: ["--[no-]stream"],
      description: "Do not attempt to optimize graph presentation, suitable for streaming large graphs.") {|arg| arg},
    RDF::CLI::Option.new(
      symbol: :useNativeTypes,
      datatype: TrueClass,
      control: :checkbox,
      on: ["--[no-]use-native-types"],
      description: "Use native JSON values in value objects.") {|arg| arg},
    RDF::CLI::Option.new(
      symbol: :useRdfType,
      datatype: TrueClass,
      control: :checkbox,
      on: ["--[no-]use-rdf-type"],
      description: "Treat `rdf:type` like a normal property instead of using `@type`.") {|arg| arg},
  ]
end

Public Instance Methods

write_epilogue() click to toggle source

Outputs the Serialized JSON-LD representation of all stored statements.

If provided a context or prefixes, we'll create a context and use it to compact the output. Otherwise, we return un-compacted JSON-LD

@return [void] @see write_triple

Calls superclass method
# File lib/json/ld/writer.rb, line 296
def write_epilogue
  if @options[:stream]
    stream_epilogue
  else

    log_debug("writer") { "serialize #{@repo.count} statements, #{@options.inspect}"}
    result = API.fromRdf(@repo, **@options)

    # Some options may be indicated from accept parameters
    profile = @options.fetch(:accept_params, {}).fetch(:profile, "").split(' ')
    links = LinkHeader.parse(@options[:link])
    @options[:context] ||= links.find_link(['rel', JSON_LD_NS+"context"]).href rescue nil
    @options[:context] ||= Writer.default_context if profile.include?(JSON_LD_NS+"compacted")
    @options[:frame] ||= links.find_link(['rel', JSON_LD_NS+"frame"]).href rescue nil

    # If we were provided a context, or prefixes, use them to compact the output
    context = @options[:context]
    context ||= if @options[:prefixes] || @options[:language] || @options[:standard_prefixes]
      ctx = Context.new(**@options)
      ctx.language = @options[:language] if @options[:language]
      @options[:prefixes].each do |prefix, iri|
        ctx.set_mapping(prefix, iri) if prefix && iri
      end if @options[:prefixes]
      ctx
    end

    # Rename BNodes to uniquify them, if necessary
    if options[:unique_bnodes]
      result = API.flatten(result, context, **@options)
    end

    if frame = @options[:frame]
      # Perform framing, if given a frame
      log_debug("writer") { "frame result"}
      result = API.frame(result, frame, **@options)
    elsif context
      # Perform compaction, if we have a context
      log_debug("writer") { "compact result"}
      result = API.compact(result, context,  **@options)
    end

    @output.write(result.to_json(JSON_STATE))
  end

  super
end
write_prologue() click to toggle source

Necessary for streaming @return [void] `self`

Calls superclass method
# File lib/json/ld/writer.rb, line 283
def write_prologue
  stream_prologue if @options[:stream]
  super
end
write_quad(subject, predicate, object, graph_name) click to toggle source

Outputs the N-Quads representation of a statement.

@param [RDF::Resource] subject @param [RDF::URI] predicate @param [RDF::Term] object @return [void]

# File lib/json/ld/writer.rb, line 271
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
    @repo.insert(statement)
  end
end
write_triple(subject, predicate, object) click to toggle source

Addes a triple to be serialized @param [RDF::Resource] subject @param [RDF::URI] predicate @param [RDF::Value] object @return [void] @abstract

# File lib/json/ld/writer.rb, line 260
def write_triple(subject, predicate, object)
  write_quad(subject, predicate, object, nil)
end