Class: RDF::RDFXML::Writer

Inherits:
RDF::RDFa::Writer
  • Object
show all
Includes:
Util::Logger
Defined in:
lib/rdf/rdfxml/writer.rb,
lib/rdf/rdfxml/writer/haml_templates.rb

Overview

An RDF/XML serialiser 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.

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

Examples:

Obtaining a RDF/XML writer class

RDF::Writer.for(:rdf)         #=> RDF::RDFXML::Writer
RDF::Writer.for("etc/test.rdf")
RDF::Writer.for(file_name: "etc/test.rdf")
RDF::Writer.for(file_extension: "rdf")
RDF::Writer.for(content_type: "application/rdf+xml")

Serializing RDF graph into an RDF/XML file

RDF::RDFXML::Write.open("etc/test.rdf") do |writer|
  writer << graph
end

Serializing RDF statements into an RDF/XML file

RDF::RDFXML::Writer.open("etc/test.rdf") do |writer|
  graph.each_statement do |statement|
    writer << statement
  end
end

Serializing RDF statements into an RDF/XML string

RDF::RDFXML::Writer.buffer do |writer|
  graph.each_statement do |statement|
    writer << statement
  end
end

Creating @base and @prefix definitions in output

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

Author:

Constant Summary collapse

VALID_ATTRIBUTES =
[:none, :untyped, :typed]
BASE_HAML =

The default set of HAML templates used for RDFa code generation

{
 identifier: "base", 
  # Document
  # Locals: lang, title, prefix, base, subjects
  # Yield: subjects.each
  doc: %q(
    = %(<?xml version='1.0' encoding='utf-8' ?>)
    - if stylesheet
      = %(<?xml-stylesheet type="text/xsl" href="#{stylesheet}"?>)
    %rdf:RDF{prefix_attrs.merge("xml:lang" => lang, "xml:base" => base)}
      - subjects.each do |subject|
        != yield(subject)
  ),

  # Output for non-leaf resources
  # Note that @about may be omitted for Nodes that are not referenced
  #
  # If _rel_ and _resource_ are not nil, the tag will be written relative
  # to a previous subject. If _element_ is :li, the tag will be written
  # with <li> instead of <div>.
  #
  # Locals: subject, typeof, predicates, rel, element, inlist, attr_props
  # Yield: predicates.each
  subject: %q(
    - first_type, *types = typeof.to_s.split(' ')
    - (types.unshift(first_type); first_type = nil) if first_type && (first_type.include?('/') || first_type.start_with?('_:'))
    - first_type ||= get_qname(RDF.Description)
    - first_type = first_type[1..-1] if first_type.to_s.start_with?(":")
    - attr_props = attr_props.merge(get_qname(RDF.nodeID) => subject.id) if subject.node? && ref_count(subject) >= 1
    - attr_props = attr_props.merge(get_qname(RDF.about) => relativize(subject)) if subject.uri?
    - haml_tag(first_type, attr_props) do
      - types.each do |type|
        - expanded_type = expand_curie(type)
        - if expanded_type.start_with?('_:')
          - haml_tag(get_qname(RDF.type), "rdf:nodeID" => expanded_type[2..-1])
        -else
          - haml_tag(get_qname(RDF.type), "rdf:resource" => expanded_type)
      - predicates.each do |p|
        = yield(p)
  ),

  # Output for single-valued properties
  # Locals: predicate, object, inlist
  # Yields: object
  # If nil is returned, render as a leaf
  # Otherwise, render result
  property_value: %q(
  - if recurse && res = yield(object)
    - haml_tag(property) do
      = res
  - elsif object.literal? && object.datatype == RDF.XMLLiteral
    - haml_tag(property, :"<", "rdf:parseType" => "Literal") do
      = object.value
  - elsif object.literal?
    - haml_tag(property, :"<", "xml:lang" => object.language, "rdf:datatype" => (object.datatype unless object.plain?)) do
      = object.value.to_s.encode(xml: :text)
  - elsif object.node?
    - haml_tag(property, :"/", "rdf:nodeID" => object.id)
  - else
    - haml_tag(property, :"/", "rdf:resource" => relativize(object))
  ),

  # Outpust for a list
  # Locals: predicate, list
  # Yields: object
  # If nil is returned, render as a leaf
  # Otherwise, render result
  collection: %q(
    - haml_tag(property, get_qname(RDF.parseType) => "Collection") do
      - list.each do |object|
        - if recurse && res = yield(object)
          = res
        - elsif object.node?
          - haml_tag(get_qname(RDF.Description), :"/", "rdf:nodeID" => (object.id if ref_count(object) > 1))
        - else
          - haml_tag(get_qname(RDF.Description), :"/", "rdf:about" => relativize(object))
  ),
}
HAML_TEMPLATES =
{base: BASE_HAML}
DEFAULT_HAML =
BASE_HAML

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

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

Initializes the RDF/XML writer instance.

Parameters:

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

    the output stream

  • options (Hash{Symbol => Object}) (defaults to: {})

    any additional options

Options Hash (options):

  • :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: 10

    Maximum depth for recursively defining resources

  • :lang (#to_s) — default: nil

    Output as root xml:lang attribute, and avoid generation xml:lang where possible

  • :attributes (Symbol) — default: nil

    How to use XML attributes when serializing, one of :none, :untyped, :typed. The default is :none.

  • :standard_prefixes (Boolean) — default: false

    Add standard prefixes to prefixes, if necessary.

  • :default_namespace (String) — default: nil

    URI to use as default namespace, same as prefix(nil)

  • :stylesheet (String) — default: nil

    URI to use as @href for output stylesheet processing instruction.

Yields:

  • (writer)

Yield Parameters:

  • writer (RDF::Writer)


116
117
118
# File 'lib/rdf/rdfxml/writer.rb', line 116

def initialize(output = $stdout, options = {}, &block)
  super
end

Class Method Details

.optionsObject

RDF/XML Writer options



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/rdf/rdfxml/writer.rb', line 59

def self.options
  super + [
    RDF::CLI::Option.new(
      symbol: :attributes,
      datatype: %w(none untyped typed),
      on: ["--attributes ATTRIBUTES",  %w(none untyped typed)],
      description: "How to use XML attributes when serializing, one of :none, :untyped, :typed. The default is :none.") {|arg| arg.to_sym},
    RDF::CLI::Option.new(
      symbol: :default_namespace,
      datatype: RDF::URI,
      on: ["--default-namespace URI", :REQUIRED],
      description: "URI to use as default namespace, same as prefixes.") {|arg| RDF::URI(arg)},
    RDF::CLI::Option.new(
      symbol: :lang,
      datatype: String,
      on: ["--lang"],
      description: "Output as root @lang attribute, and avoid generation _@lang_ where possible."),
    RDF::CLI::Option.new(
      symbol: :max_depth,
      datatype: Integer,
      on: ["--max-depth"],
      description: "Maximum depth for recursively defining resources, defaults to 3.") {|arg| arg.to_i},
    RDF::CLI::Option.new(
      symbol: :stylesheet,
      datatype: RDF::URI,
      on: ["--stylesheet URI", :REQUIRED],
      description: "URI to use as @href for output stylesheet processing instruction.") {|arg| RDF::URI(arg)},
  ]
end

Instance Method Details

#haml_templateHash<Symbol => String>

Returns:

  • (Hash<Symbol => String>)


121
122
123
124
125
126
127
# File 'lib/rdf/rdfxml/writer.rb', line 121

def haml_template
  return @haml_template if @haml_template
  case @options[:haml]
  when Hash             then @options[:haml]
  else                       DEFAULT_HAML
  end
end

#write_epilogueObject



129
130
131
132
133
134
135
# File 'lib/rdf/rdfxml/writer.rb', line 129

def write_epilogue
  @force_RDF_about = {}
  @max_depth = @options.fetch(:max_depth, 10)
  @attributes = @options.fetch(:attributes, :none)

  super
end