rdf-trix 0.2.0

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/AUTHORS ADDED
@@ -0,0 +1 @@
1
+ * Arto Bendiken <arto.bendiken@gmail.com>
data/README ADDED
@@ -0,0 +1,59 @@
1
+ TriX Support for RDF.rb
2
+ =======================
3
+
4
+ This is an [RDF.rb][] plugin that adds support for parsing/serializing
5
+ [TriX][], an XML-based RDF serialization format developed by HP Labs and
6
+ Nokia.
7
+
8
+ * <http://github.com/bendiken/rdf-trix>
9
+ * <http://blog.datagraph.org/2010/04/parsing-rdf-with-ruby>
10
+
11
+ Documentation
12
+ -------------
13
+
14
+ * {RDF::TriX}
15
+ * {RDF::TriX::Format}
16
+ * {RDF::TriX::Reader}
17
+ * {RDF::TriX::Writer}
18
+
19
+ Dependencies
20
+ ------------
21
+
22
+ * [RDF.rb](http://rubygems.org/gems/rdf) (>= 0.2.0)
23
+ * [REXML](http://ruby-doc.org/stdlib/libdoc/rexml/rdoc/) (>= 3.1.7),
24
+ [LibXML-Ruby](http://rubygems.org/gems/libxml-ruby) (>= 1.1.4), or
25
+ [Nokogiri](http://rubygems.org/gems/nokogiri) (>= 1.4.2)
26
+
27
+ Installation
28
+ ------------
29
+
30
+ The recommended installation method is via [RubyGems](http://rubygems.org/).
31
+ To install the latest official release of the `RDF::TriX` gem, do:
32
+
33
+ % [sudo] gem install rdf-trix
34
+
35
+ Download
36
+ --------
37
+
38
+ To get a local working copy of the development repository, do:
39
+
40
+ % git clone git://github.com/bendiken/rdf-trix.git
41
+
42
+ Alternatively, you can download the latest development version as a tarball
43
+ as follows:
44
+
45
+ % wget http://github.com/bendiken/rdf-trix/tarball/master
46
+
47
+ Author
48
+ ------
49
+
50
+ * [Arto Bendiken](mailto:arto.bendiken@gmail.com) - <http://ar.to/>
51
+
52
+ License
53
+ -------
54
+
55
+ `RDF::TriX` is free and unencumbered public domain software. For more
56
+ information, see <http://unlicense.org/> or the accompanying UNLICENSE file.
57
+
58
+ [RDF.rb]: http://rdf.rubyforge.org/
59
+ [TriX]: http://www.w3.org/2004/03/trix/
data/UNLICENSE ADDED
@@ -0,0 +1,24 @@
1
+ This is free and unencumbered software released into the public domain.
2
+
3
+ Anyone is free to copy, modify, publish, use, compile, sell, or
4
+ distribute this software, either in source code form or as a compiled
5
+ binary, for any purpose, commercial or non-commercial, and by any
6
+ means.
7
+
8
+ In jurisdictions that recognize copyright laws, the author or authors
9
+ of this software dedicate any and all copyright interest in the
10
+ software to the public domain. We make this dedication for the benefit
11
+ of the public at large and to the detriment of our heirs and
12
+ successors. We intend this dedication to be an overt act of
13
+ relinquishment in perpetuity of all present and future rights to this
14
+ software under copyright law.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ For more information, please refer to <http://unlicense.org/>
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.0
data/etc/doap.xml ADDED
@@ -0,0 +1,115 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <TriX xmlns="http://www.w3.org/2004/03/trix/trix-1/">
3
+ <graph>
4
+ <triple>
5
+ <uri>http://ar.to/#self</uri>
6
+ <uri>http://www.w3.org/1999/02/22-rdf-syntax-ns#type</uri>
7
+ <uri>http://xmlns.com/foaf/0.1/Person</uri>
8
+ </triple>
9
+ <triple>
10
+ <uri>http://ar.to/#self</uri>
11
+ <uri>http://www.w3.org/2000/01/rdf-schema#isDefinedBy</uri>
12
+ <uri>http://datagraph.org/bendiken/foaf</uri>
13
+ </triple>
14
+ <triple>
15
+ <uri>http://ar.to/#self</uri>
16
+ <uri>http://xmlns.com/foaf/0.1/made</uri>
17
+ <uri>http://rubygems.org/gems/rdf-trix</uri>
18
+ </triple>
19
+ <triple>
20
+ <uri>http://ar.to/#self</uri>
21
+ <uri>http://xmlns.com/foaf/0.1/mbox</uri>
22
+ <uri>mailto:arto.bendiken@gmail.com</uri>
23
+ </triple>
24
+ <triple>
25
+ <uri>http://ar.to/#self</uri>
26
+ <uri>http://xmlns.com/foaf/0.1/name</uri>
27
+ <plainLiteral>Arto Bendiken</plainLiteral>
28
+ </triple>
29
+ <triple>
30
+ <uri>http://rubygems.org/gems/rdf-trix</uri>
31
+ <uri>http://purl.org/dc/terms/creator</uri>
32
+ <uri>http://ar.to/#self</uri>
33
+ </triple>
34
+ <triple>
35
+ <uri>http://rubygems.org/gems/rdf-trix</uri>
36
+ <uri>http://usefulinc.com/ns/doap#blog</uri>
37
+ <uri>http://ar.to/</uri>
38
+ </triple>
39
+ <triple>
40
+ <uri>http://rubygems.org/gems/rdf-trix</uri>
41
+ <uri>http://usefulinc.com/ns/doap#blog</uri>
42
+ <uri>http://blog.datagraph.org/</uri>
43
+ </triple>
44
+ <triple>
45
+ <uri>http://rubygems.org/gems/rdf-trix</uri>
46
+ <uri>http://usefulinc.com/ns/doap#bug-database</uri>
47
+ <uri>http://github.com/bendiken/rdf-trix/issues</uri>
48
+ </triple>
49
+ <triple>
50
+ <uri>http://rubygems.org/gems/rdf-trix</uri>
51
+ <uri>http://usefulinc.com/ns/doap#created</uri>
52
+ <plainLiteral>2010-02-02</plainLiteral>
53
+ </triple>
54
+ <triple>
55
+ <uri>http://rubygems.org/gems/rdf-trix</uri>
56
+ <uri>http://usefulinc.com/ns/doap#description</uri>
57
+ <plainLiteral xml:lang="en">RDF.rb plugin for parsing/serializing TriX data.</plainLiteral>
58
+ </triple>
59
+ <triple>
60
+ <uri>http://rubygems.org/gems/rdf-trix</uri>
61
+ <uri>http://usefulinc.com/ns/doap#developer</uri>
62
+ <uri>http://ar.to/#self</uri>
63
+ </triple>
64
+ <triple>
65
+ <uri>http://rubygems.org/gems/rdf-trix</uri>
66
+ <uri>http://usefulinc.com/ns/doap#documenter</uri>
67
+ <uri>http://ar.to/#self</uri>
68
+ </triple>
69
+ <triple>
70
+ <uri>http://rubygems.org/gems/rdf-trix</uri>
71
+ <uri>http://usefulinc.com/ns/doap#download-page</uri>
72
+ <uri>http://rubyforge.org/projects/rdf/</uri>
73
+ </triple>
74
+ <triple>
75
+ <uri>http://rubygems.org/gems/rdf-trix</uri>
76
+ <uri>http://usefulinc.com/ns/doap#homepage</uri>
77
+ <uri>http://rdf.rubyforge.org/trix/</uri>
78
+ </triple>
79
+ <triple>
80
+ <uri>http://rubygems.org/gems/rdf-trix</uri>
81
+ <uri>http://usefulinc.com/ns/doap#license</uri>
82
+ <uri>http://creativecommons.org/licenses/publicdomain/</uri>
83
+ </triple>
84
+ <triple>
85
+ <uri>http://rubygems.org/gems/rdf-trix</uri>
86
+ <uri>http://usefulinc.com/ns/doap#maintainer</uri>
87
+ <uri>http://ar.to/#self</uri>
88
+ </triple>
89
+ <triple>
90
+ <uri>http://rubygems.org/gems/rdf-trix</uri>
91
+ <uri>http://usefulinc.com/ns/doap#name</uri>
92
+ <plainLiteral>RDF::TriX</plainLiteral>
93
+ </triple>
94
+ <triple>
95
+ <uri>http://rubygems.org/gems/rdf-trix</uri>
96
+ <uri>http://usefulinc.com/ns/doap#platform</uri>
97
+ <plainLiteral>Ruby</plainLiteral>
98
+ </triple>
99
+ <triple>
100
+ <uri>http://rubygems.org/gems/rdf-trix</uri>
101
+ <uri>http://usefulinc.com/ns/doap#shortdesc</uri>
102
+ <plainLiteral xml:lang="en">TriX support for RDF.rb.</plainLiteral>
103
+ </triple>
104
+ <triple>
105
+ <uri>http://rubygems.org/gems/rdf-trix</uri>
106
+ <uri>http://www.w3.org/1999/02/22-rdf-syntax-ns#type</uri>
107
+ <uri>http://usefulinc.com/ns/doap#Project</uri>
108
+ </triple>
109
+ <triple>
110
+ <uri>http://rubygems.org/gems/rdf-trix</uri>
111
+ <uri>http://xmlns.com/foaf/0.1/maker</uri>
112
+ <uri>http://ar.to/#self</uri>
113
+ </triple>
114
+ </graph>
115
+ </TriX>
data/lib/rdf/trix.rb ADDED
@@ -0,0 +1,36 @@
1
+ require 'rdf'
2
+
3
+ module RDF
4
+ ##
5
+ # **`RDF::TriX`** is a TriX plugin for RDF.rb.
6
+ #
7
+ # @example Requiring the `RDF::TriX` module
8
+ # require 'rdf/trix'
9
+ #
10
+ # @example Parsing RDF statements from a TriX file
11
+ # RDF::TriX::Reader.open("etc/doap.xml") do |reader|
12
+ # reader.each_statement do |statement|
13
+ # puts statement.inspect
14
+ # end
15
+ # end
16
+ #
17
+ # @example Serializing RDF statements into a TriX file
18
+ # RDF::TriX::Writer.open("etc/test.xml") do |writer|
19
+ # reader.each_statement do |statement|
20
+ # writer << statement
21
+ # end
22
+ # end
23
+ #
24
+ # @see http://rdf.rubyforge.org/
25
+ # @see http://www.w3.org/2004/03/trix/
26
+ # @see http://www.hpl.hp.com/techreports/2004/HPL-2004-56.pdf
27
+ # @see http://swdev.nokia.com/trix/trix.html
28
+ #
29
+ # @author [Arto Bendiken](http://ar.to/)
30
+ module TriX
31
+ require 'rdf/trix/format'
32
+ autoload :Reader, 'rdf/trix/reader'
33
+ autoload :Writer, 'rdf/trix/writer'
34
+ autoload :VERSION, 'rdf/trix/version'
35
+ end # module TriX
36
+ end # module RDF
@@ -0,0 +1,22 @@
1
+ module RDF::TriX
2
+ ##
3
+ # TriX format specification.
4
+ #
5
+ # @example Obtaining a TriX format class
6
+ # RDF::Format.for(:trix) #=> RDF::TriX::Format
7
+ # RDF::Format.for("etc/doap.xml")
8
+ # RDF::Format.for(:file_name => "etc/doap.xml")
9
+ # RDF::Format.for(:file_extension => "xml")
10
+ # RDF::Format.for(:content_type => "application/trix")
11
+ #
12
+ # @see http://www.w3.org/2004/03/trix/
13
+ class Format < RDF::Format
14
+ content_type 'application/trix', :extension => :xml
15
+ content_encoding 'utf-8'
16
+
17
+ reader { RDF::TriX::Reader }
18
+ writer { RDF::TriX::Writer }
19
+
20
+ XMLNS = 'http://www.w3.org/2004/03/trix/trix-1/'
21
+ end # class Format
22
+ end # module RDF::TriX
@@ -0,0 +1,151 @@
1
+ module RDF::TriX
2
+ ##
3
+ # TriX parser.
4
+ #
5
+ # This class supports [REXML][], [LibXML][] and [Nokogiri][] for XML
6
+ # processing, and will automatically select the most performant
7
+ # implementation (Nokogiri or LibXML) that is available. If need be, you
8
+ # can explicitly override the used implementation by passing in a
9
+ # `:library` option to `Reader.new` or `Reader.open`.
10
+ #
11
+ # [REXML]: http://www.germane-software.com/software/rexml/
12
+ # [LibXML]: http://libxml.rubyforge.org/rdoc/
13
+ # [Nokogiri]: http://nokogiri.org/
14
+ #
15
+ # @example Obtaining a TriX reader class
16
+ # RDF::Reader.for(:trix) #=> RDF::TriX::Reader
17
+ # RDF::Reader.for("etc/doap.xml")
18
+ # RDF::Reader.for(:file_name => "etc/doap.xml")
19
+ # RDF::Reader.for(:file_extension => "xml")
20
+ # RDF::Reader.for(:content_type => "application/trix")
21
+ #
22
+ # @example Instantiating a Nokogiri-based reader
23
+ # RDF::TriX::Reader.new(input, :library => :nokogiri)
24
+ #
25
+ # @example Instantiating a LibXML-based reader
26
+ # RDF::TriX::Reader.new(input, :library => :libxml)
27
+ #
28
+ # @example Instantiating a REXML-based reader
29
+ # RDF::TriX::Reader.new(input, :library => :rexml)
30
+ #
31
+ # @example Parsing RDF statements from a TriX file
32
+ # RDF::TriX::Reader.open("etc/doap.xml") do |reader|
33
+ # reader.each_statement do |statement|
34
+ # puts statement.inspect
35
+ # end
36
+ # end
37
+ #
38
+ # @example Parsing RDF statements from a TriX string
39
+ # data = StringIO.new(File.read("etc/doap.xml"))
40
+ # RDF::TriX::Reader.new(data) do |reader|
41
+ # reader.each_statement do |statement|
42
+ # puts statement.inspect
43
+ # end
44
+ # end
45
+ #
46
+ # @see http://www.w3.org/2004/03/trix/
47
+ class Reader < RDF::Reader
48
+ format RDF::TriX::Format
49
+
50
+ ##
51
+ # Returns the XML implementation module for this reader instance.
52
+ #
53
+ # @return [Module]
54
+ attr_reader :implementation
55
+
56
+ ##
57
+ # Initializes the TriX reader instance.
58
+ #
59
+ # @param [IO, File, String] input
60
+ # @param [Hash{Symbol => Object}] options
61
+ # @option options [Symbol] :library (:nokogiri, :libxml, or :rexml)
62
+ # @yield [reader]
63
+ # @yieldparam [Reader] reader
64
+ def initialize(input = $stdin, options = {}, &block)
65
+ super do
66
+ @library = case options[:library]
67
+ when nil
68
+ # Use Nokogiri or LibXML when available, and REXML otherwise:
69
+ begin
70
+ require 'nokogiri'
71
+ :nokogiri
72
+ rescue LoadError => e
73
+ begin
74
+ require 'libxml'
75
+ :libxml
76
+ rescue LoadError => e
77
+ :rexml
78
+ end
79
+ end
80
+ when :nokogiri, :libxml, :rexml
81
+ options[:library]
82
+ else
83
+ raise ArgumentError.new("expected :rexml, :libxml or :nokogiri, but got #{options[:library].inspect}")
84
+ end
85
+
86
+ require "rdf/trix/reader/#{@library}"
87
+ @implementation = case @library
88
+ when :nokogiri then Nokogiri
89
+ when :libxml then LibXML
90
+ when :rexml then REXML
91
+ end
92
+ self.extend(@implementation)
93
+
94
+ initialize_xml(options)
95
+ block.call(self) if block_given?
96
+ end
97
+ end
98
+
99
+ ##
100
+ # @private
101
+ # @see RDF::Reader#each_triple
102
+ def each_triple(&block)
103
+ unless block_given?
104
+ enum_for(:each_triple)
105
+ else
106
+ each_statement do |statement|
107
+ block.call(*statement.to_triple)
108
+ end
109
+ end
110
+ end
111
+
112
+ ##
113
+ # @private
114
+ # @see RDF::Reader#each_quad
115
+ def each_quad(&block)
116
+ unless block_given?
117
+ enum_for(:each_quad)
118
+ else
119
+ each_statement do |statement|
120
+ block.call(*statement.to_quad)
121
+ end
122
+ end
123
+ end
124
+
125
+ ##
126
+ # Returns the RDF value of the given TriX element.
127
+ #
128
+ # @param [String] name
129
+ # @param [Hash{String => Object}] attributes
130
+ # @param [String] content
131
+ # @return [RDF::Value]
132
+ def parse_element(name, attributes, content)
133
+ case name.to_sym
134
+ when :id
135
+ RDF::Node.new(content.strip)
136
+ when :uri
137
+ RDF::URI.new(content.strip)
138
+ when :typedLiteral
139
+ RDF::Literal.new(content, :datatype => attributes['datatype'])
140
+ when :plainLiteral
141
+ if lang = attributes['xml:lang'] || attributes['lang']
142
+ RDF::Literal.new(content, :language => lang)
143
+ else
144
+ RDF::Literal.new(content)
145
+ end
146
+ else
147
+ # TODO: raise error
148
+ end
149
+ end
150
+ end # class Reader
151
+ end # module RDF::TriX
@@ -0,0 +1,82 @@
1
+ module RDF::TriX
2
+ class Reader < RDF::Reader
3
+ ##
4
+ # LibXML-Ruby implementation of the TriX reader.
5
+ #
6
+ # @see http://libxml.rubyforge.org/rdoc/
7
+ module LibXML
8
+ OPTIONS = {'trix' => Format::XMLNS}.freeze
9
+
10
+ ##
11
+ # Returns the name of the underlying XML library.
12
+ #
13
+ # @return [Symbol]
14
+ def self.library
15
+ :libxml
16
+ end
17
+
18
+ ##
19
+ # Initializes the underlying XML library.
20
+ #
21
+ # @param [Hash{Symbol => Object}] options
22
+ # @return [void]
23
+ def initialize_xml(options = {})
24
+ require 'libxml' unless defined?(::LibXML)
25
+ @xml = case @input
26
+ when File then ::LibXML::XML::Document.file(@input.path)
27
+ when IO then ::LibXML::XML::Document.io(@input)
28
+ else ::LibXML::XML::Document.string(@input.to_s)
29
+ end
30
+ end
31
+
32
+ ##
33
+ # @private
34
+ # @see RDF::Reader#each_graph
35
+ def each_graph(&block)
36
+ unless block_given?
37
+ enum_for(:each_graph)
38
+ else
39
+ @xml.find('//trix:graph', OPTIONS).each do |graph_element|
40
+ graph = RDF::Graph.new(read_context(graph_element))
41
+ read_statements(graph_element) { |statement| graph << statement }
42
+ block.call(graph)
43
+ end
44
+ end
45
+ end
46
+
47
+ ##
48
+ # @private
49
+ # @see RDF::Reader#each_statement
50
+ def each_statement(&block)
51
+ unless block_given?
52
+ enum_for(:each_statement)
53
+ else
54
+ @xml.find('//trix:graph', OPTIONS).each do |graph_element|
55
+ read_statements(graph_element, &block)
56
+ end
57
+ end
58
+ end
59
+
60
+ protected
61
+
62
+ ##
63
+ # @private
64
+ def read_context(graph_element)
65
+ name = graph_element.children.select { |node| node.element? && node.name.to_s == 'uri' }.first.content.strip rescue nil
66
+ name ? RDF::URI.intern(name) : nil
67
+ end
68
+
69
+ ##
70
+ # @private
71
+ def read_statements(graph_element, &block)
72
+ context = read_context(graph_element)
73
+ graph_element.find('./trix:triple', OPTIONS).each do |triple_element|
74
+ triple = triple_element.children.select { |node| node.element? }[0..2]
75
+ triple = triple.map { |element| parse_element(element.name, element.attributes, element.content) }
76
+ triple << {:context => context} if context
77
+ block.call(RDF::Statement.new(*triple))
78
+ end
79
+ end
80
+ end # module LibXML
81
+ end # class Reader
82
+ end # module RDF::TriX
@@ -0,0 +1,78 @@
1
+ module RDF::TriX
2
+ class Reader < RDF::Reader
3
+ ##
4
+ # Nokogiri implementation of the TriX reader.
5
+ #
6
+ # @see http://nokogiri.org/
7
+ module Nokogiri
8
+ OPTIONS = {'trix' => Format::XMLNS}.freeze
9
+
10
+ ##
11
+ # Returns the name of the underlying XML library.
12
+ #
13
+ # @return [Symbol]
14
+ def self.library
15
+ :nokogiri
16
+ end
17
+
18
+ ##
19
+ # Initializes the underlying XML library.
20
+ #
21
+ # @param [Hash{Symbol => Object}] options
22
+ # @return [void]
23
+ def initialize_xml(options = {})
24
+ require 'nokogiri' unless defined?(::Nokogiri)
25
+ @xml = ::Nokogiri::XML(@input)
26
+ end
27
+
28
+ ##
29
+ # @private
30
+ # @see RDF::Reader#each_graph
31
+ def each_graph(&block)
32
+ unless block_given?
33
+ enum_for(:each_graph)
34
+ else
35
+ @xml.xpath('//trix:graph', OPTIONS).each do |graph_element|
36
+ graph = RDF::Graph.new(read_context(graph_element))
37
+ read_statements(graph_element) { |statement| graph << statement }
38
+ block.call(graph)
39
+ end
40
+ end
41
+ end
42
+
43
+ ##
44
+ # @private
45
+ # @see RDF::Reader#each_statement
46
+ def each_statement(&block)
47
+ unless block_given?
48
+ enum_for(:each_statement)
49
+ else
50
+ @xml.xpath('//trix:graph', OPTIONS).each do |graph_element|
51
+ read_statements(graph_element, &block)
52
+ end
53
+ end
54
+ end
55
+
56
+ protected
57
+
58
+ ##
59
+ # @private
60
+ def read_context(graph_element)
61
+ name = graph_element.children.select { |node| node.element? && node.name.to_s == 'uri' }.first.content.strip rescue nil
62
+ name ? RDF::URI.intern(name) : nil
63
+ end
64
+
65
+ ##
66
+ # @private
67
+ def read_statements(graph_element, &block)
68
+ context = read_context(graph_element)
69
+ graph_element.xpath('./trix:triple', OPTIONS).each do |triple_element|
70
+ triple = triple_element.children.select { |node| node.element? }[0..2]
71
+ triple = triple.map { |element| parse_element(element.name, element, element.content) }
72
+ triple << {:context => context} if context
73
+ block.call(RDF::Statement.new(*triple))
74
+ end
75
+ end
76
+ end # module Nokogiri
77
+ end # class Reader
78
+ end # module RDF::TriX
@@ -0,0 +1,78 @@
1
+ module RDF::TriX
2
+ class Reader < RDF::Reader
3
+ ##
4
+ # REXML implementation of the TriX reader.
5
+ #
6
+ # @see http://www.germane-software.com/software/rexml/
7
+ module REXML
8
+ OPTIONS = {}.freeze
9
+
10
+ ##
11
+ # Returns the name of the underlying XML library.
12
+ #
13
+ # @return [Symbol]
14
+ def self.library
15
+ :rexml
16
+ end
17
+
18
+ ##
19
+ # Initializes the underlying XML library.
20
+ #
21
+ # @param [Hash{Symbol => Object}] options
22
+ # @return [void]
23
+ def initialize_xml(options = {})
24
+ require 'rexml/document' unless defined?(::REXML)
25
+ @xml = ::REXML::Document.new(@input, :compress_whitespace => %w{uri})
26
+ end
27
+
28
+ ##
29
+ # @private
30
+ # @see RDF::Reader#each_graph
31
+ def each_graph(&block)
32
+ unless block_given?
33
+ enum_for(:each_graph)
34
+ else
35
+ @xml.elements.each('TriX/graph') do |graph_element|
36
+ graph = RDF::Graph.new(read_context(graph_element))
37
+ read_statements(graph_element) { |statement| graph << statement }
38
+ block.call(graph)
39
+ end
40
+ end
41
+ end
42
+
43
+ ##
44
+ # @private
45
+ # @see RDF::Reader#each_statement
46
+ def each_statement(&block)
47
+ unless block_given?
48
+ enum_for(:each_statement)
49
+ else
50
+ @xml.elements.each('TriX/graph') do |graph_element|
51
+ read_statements(graph_element, &block)
52
+ end
53
+ end
54
+ end
55
+
56
+ protected
57
+
58
+ ##
59
+ # @private
60
+ def read_context(graph_element)
61
+ name = graph_element.elements.select { |element| element.name.to_s == 'uri' }.first.text.strip rescue nil
62
+ name ? RDF::URI.intern(name) : nil
63
+ end
64
+
65
+ ##
66
+ # @private
67
+ def read_statements(graph_element, &block)
68
+ context = read_context(graph_element)
69
+ graph_element.elements.each('triple') do |triple_element|
70
+ triple = triple_element.elements.to_a[0..2]
71
+ triple = triple.map { |element| parse_element(element.name, element.attributes, element.text) }
72
+ triple << {:context => context} if context
73
+ block.call(RDF::Statement.new(*triple))
74
+ end
75
+ end
76
+ end # module REXML
77
+ end # class Reader
78
+ end # module RDF::TriX
@@ -0,0 +1,22 @@
1
+ module RDF module TriX
2
+ module VERSION
3
+ MAJOR = 0
4
+ MINOR = 2
5
+ TINY = 0
6
+ EXTRA = nil
7
+
8
+ STRING = [MAJOR, MINOR, TINY, EXTRA].compact.join('.')
9
+
10
+ ##
11
+ # @return [String]
12
+ def self.to_s() STRING end
13
+
14
+ ##
15
+ # @return [String]
16
+ def self.to_str() STRING end
17
+
18
+ ##
19
+ # @return [Array(Integer, Integer, Integer)]
20
+ def self.to_a() [MAJOR, MINOR, TINY] end
21
+ end
22
+ end end
@@ -0,0 +1,236 @@
1
+ module RDF::TriX
2
+ ##
3
+ # TriX serializer.
4
+ #
5
+ # This class supports both [REXML][] and [Nokogiri][] for XML processing,
6
+ # and will automatically select the most performant implementation
7
+ # (Nokogiri) when it is available. If need be, you can explicitly
8
+ # override the used implementation by passing in a `:library` option to
9
+ # `Writer.new` or `Writer.open`.
10
+ #
11
+ # [REXML]: http://www.germane-software.com/software/rexml/
12
+ # [LibXML]: http://libxml.rubyforge.org/rdoc/
13
+ # [Nokogiri]: http://nokogiri.org/
14
+ #
15
+ # @example Obtaining a TriX writer class
16
+ # RDF::Writer.for(:trix) #=> RDF::TriX::Writer
17
+ # RDF::Writer.for("etc/test.xml")
18
+ # RDF::Writer.for(:file_name => "etc/test.xml")
19
+ # RDF::Writer.for(:file_extension => "xml")
20
+ # RDF::Writer.for(:content_type => "application/trix")
21
+ #
22
+ # @example Instantiating a Nokogiri-based writer
23
+ # RDF::TriX::Writer.new(output, :library => :nokogiri)
24
+ #
25
+ # @example Instantiating a REXML-based writer
26
+ # RDF::TriX::Writer.new(output, :library => :rexml)
27
+ #
28
+ # @example Serializing RDF statements into a TriX file
29
+ # RDF::TriX::Writer.open("etc/test.xml") do |writer|
30
+ # graph.each_statement do |statement|
31
+ # writer << statement
32
+ # end
33
+ # end
34
+ #
35
+ # @example Serializing RDF statements into a TriX string
36
+ # RDF::TriX::Writer.buffer do |writer|
37
+ # graph.each_statement do |statement|
38
+ # writer << statement
39
+ # end
40
+ # end
41
+ #
42
+ # @see http://www.w3.org/2004/03/trix/
43
+ class Writer < RDF::Writer
44
+ format RDF::TriX::Format
45
+
46
+ ##
47
+ # Returns the XML implementation module for this writer instance.
48
+ #
49
+ # @return [Module]
50
+ attr_reader :implementation
51
+
52
+ ##
53
+ # Returns the current named graph context, if any.
54
+ #
55
+ # @return [RDF::Resource]
56
+ attr_reader :context
57
+
58
+ ##
59
+ # Initializes the TriX writer instance.
60
+ #
61
+ # @param [IO, File] output
62
+ # @param [Hash{Symbol => Object}] options
63
+ # @option options [Symbol] :library (:nokogiri or :rexml)
64
+ # @option options [String, #to_s] :encoding ('utf-8')
65
+ # @option options [Integer] :indent (2)
66
+ # @yield [writer]
67
+ # @yieldparam [Writer] writer
68
+ def initialize(output = $stdout, options = {}, &block)
69
+ @context = nil
70
+ @nesting = 0
71
+
72
+ @library = case options[:library]
73
+ when nil
74
+ # Use Nokogiri or LibXML when available, and REXML otherwise:
75
+ begin
76
+ require 'nokogiri'
77
+ :nokogiri
78
+ rescue LoadError => e
79
+ begin
80
+ require 'libxml'
81
+ :rexml # FIXME: no LibXML support implemented yet
82
+ rescue LoadError => e
83
+ :rexml
84
+ end
85
+ end
86
+ when :libxml then :rexml # FIXME
87
+ when :nokogiri, :libxml, :rexml
88
+ options[:library]
89
+ else
90
+ raise ArgumentError.new("expected :rexml, :libxml or :nokogiri, but got #{options[:library].inspect}")
91
+ end
92
+
93
+ require "rdf/trix/writer/#{@library}"
94
+ @implementation = case @library
95
+ when :nokogiri then Nokogiri
96
+ when :libxml then LibXML # TODO
97
+ when :rexml then REXML
98
+ end
99
+ self.extend(@implementation)
100
+
101
+ @encoding = (options[:encoding] || 'utf-8').to_s
102
+ initialize_xml(options)
103
+ super
104
+ end
105
+
106
+ ##
107
+ # Defines a named graph context.
108
+ #
109
+ # @param [RDF::Resource] name
110
+ # @yield [writer]
111
+ # @yieldparam [RDF::TriX::Writer] writer
112
+ # @return [void]
113
+ def graph(name = nil, &block)
114
+ @nesting += 1
115
+ @graph = create_graph(@context = name)
116
+ if block_given?
117
+ case block.arity
118
+ when 1 then block.call(self)
119
+ else instance_eval(&block)
120
+ end
121
+ end
122
+ @graph = nil
123
+ @nesting -= 1
124
+ end
125
+
126
+ ##
127
+ # Returns `true` if we are currently in a `writer.graph { ... }` block.
128
+ #
129
+ # @return [Boolean]
130
+ def nested?
131
+ @nesting > 0
132
+ end
133
+
134
+ protected :nested?
135
+
136
+ ##
137
+ # Generates an XML comment.
138
+ #
139
+ # @param [String, #to_s] text
140
+ # @return [void]
141
+ # @see RDF::Writer#write_comment
142
+ def write_comment(text)
143
+ (@graph || @trix) << create_comment(text)
144
+ end
145
+
146
+ ##
147
+ # @private
148
+ # @see RDF::Writer#write_graph
149
+ # @since 0.2.0
150
+ def write_graph(graph)
151
+ @graph = create_graph(@context = graph.context)
152
+ graph.each_triple { |*triple| write_triple(*triple) }
153
+ end
154
+
155
+ ##
156
+ # Generates the TriX representation of an RDF statement.
157
+ #
158
+ # @param [RDF::Statement] statement
159
+ # @return [void]
160
+ def write_statement(statement)
161
+ unless nested? || statement.context.to_s == @context.to_s
162
+ @graph = create_graph(@context = statement.context)
163
+ end
164
+ write_triple(*statement.to_triple)
165
+ end
166
+
167
+ ##
168
+ # Generates the TriX representation of a triple.
169
+ #
170
+ # @param [RDF::Resource] subject
171
+ # @param [RDF::URI] predicate
172
+ # @param [RDF::Value] object
173
+ # @return [void]
174
+ def write_triple(subject, predicate, object)
175
+ @graph = create_graph unless @graph
176
+ @graph << format_triple(subject, predicate, object)
177
+ end
178
+
179
+ ##
180
+ # Returns the TriX representation of a triple.
181
+ #
182
+ # @param [RDF::Resource] subject
183
+ # @param [RDF::URI] predicate
184
+ # @param [RDF::Value] object
185
+ # @param [Hash{Symbol => Object}] options
186
+ # @return [Element]
187
+ def format_triple(subject, predicate, object, options = {})
188
+ create_element(:triple) do |triple|
189
+ triple << format_value(subject, options)
190
+ triple << format_value(predicate, options)
191
+ triple << format_value(object, options)
192
+ end
193
+ end
194
+
195
+ ##
196
+ # Returns the TriX representation of a blank node.
197
+ #
198
+ # @param [RDF::Node] value
199
+ # @param [Hash{Symbol => Object}] options
200
+ # @return [Element]
201
+ def format_node(value, options = {})
202
+ create_element(:id, value.id.to_s)
203
+ end
204
+
205
+ ##
206
+ # Returns the TriX representation of a URI reference.
207
+ #
208
+ # @param [RDF::URI] value
209
+ # @param [Hash{Symbol => Object}] options
210
+ # @return [Element]
211
+ def format_uri(value, options = {})
212
+ create_element(:uri, value.to_s)
213
+ end
214
+
215
+ ##
216
+ # Returns the TriX representation of a literal.
217
+ #
218
+ # @param [RDF::Literal, String, #to_s] value
219
+ # @param [Hash{Symbol => Object}] options
220
+ # @return [Element]
221
+ def format_literal(value, options = {})
222
+ value = RDF::Literal.new(value) unless value.is_a?(RDF::Literal) # FIXME: remove after RDF.rb 0.2.1
223
+ case
224
+ when value.has_datatype?
225
+ create_element(:typedLiteral, value.value.to_s, 'datatype' => value.datatype.to_s)
226
+ when value.has_language?
227
+ create_element(:plainLiteral, value.value.to_s, 'xml:lang' => value.language.to_s)
228
+ else
229
+ create_element(:plainLiteral, value.value.to_s)
230
+ end
231
+ end
232
+
233
+ alias_method :insert_graph, :write_graph # FIXME: remove after RDF.rb 0.2.1
234
+ alias_method :insert_statement, :write_statement # FIXME: remove after RDF.rb 0.2.1
235
+ end # class Writer
236
+ end # module RDF::TriX
@@ -0,0 +1,93 @@
1
+ module RDF::TriX
2
+ class Writer < RDF::Writer
3
+ ##
4
+ # Nokogiri implementation of the TriX writer.
5
+ #
6
+ # @see http://nokogiri.org/
7
+ module Nokogiri
8
+ ##
9
+ # Returns the name of the underlying XML library.
10
+ #
11
+ # @return [Symbol]
12
+ def self.library
13
+ :nokogiri
14
+ end
15
+
16
+ ##
17
+ # Initializes the underlying XML library.
18
+ #
19
+ # @param [Hash{Symbol => Object}] options
20
+ # @return [void]
21
+ def initialize_xml(options = {})
22
+ require 'nokogiri' unless defined?(::Nokogiri)
23
+ @xml = ::Nokogiri::XML::Document.new
24
+ @xml.encoding = @encoding
25
+ end
26
+
27
+ ##
28
+ # Generates the TriX root element.
29
+ #
30
+ # @return [void]
31
+ def write_prologue
32
+ @xml << (@trix = create_element(:TriX, nil, :xmlns => Format::XMLNS))
33
+ end
34
+
35
+ ##
36
+ # Outputs the TriX document.
37
+ #
38
+ # @return [void]
39
+ def write_epilogue
40
+ puts @xml.to_xml
41
+ @xml = @trix = nil
42
+ end
43
+
44
+ ##
45
+ # Creates an XML graph element with the given `name`.
46
+ #
47
+ # @param [RDF::Resource] name
48
+ # @yield [element]
49
+ # @yieldparam [Nokogiri::XML::Element] element
50
+ # @return [Nokogiri::XML::Element]
51
+ def create_graph(name = nil, &block)
52
+ @trix << (graph = create_element(:graph))
53
+ case name
54
+ when nil then nil
55
+ when RDF::Node then graph << create_element(:id, name.to_s) # non-standard
56
+ else graph << create_element(:uri, name.to_s)
57
+ end
58
+ block.call(graph) if block_given?
59
+ graph
60
+ end
61
+
62
+ ##
63
+ # Creates an XML comment element with the given `text`.
64
+ #
65
+ # @param [String, #to_s] text
66
+ # @return [Nokogiri::XML::Comment]
67
+ def create_comment(text)
68
+ ::Nokogiri::XML::Comment.new(@xml, text.to_s)
69
+ end
70
+
71
+ ##
72
+ # Creates an XML element of the given `name`, with optional given
73
+ # `content` and `attributes`.
74
+ #
75
+ # @param [Symbol, String, #to_s] name
76
+ # @param [String, #to_s] content
77
+ # @param [Hash{Symbol => Object}] attributes
78
+ # @yield [element]
79
+ # @yieldparam [Nokogiri::XML::Element] element
80
+ # @return [Nokogiri::XML::Element]
81
+ def create_element(name, content = nil, attributes = {}, &block)
82
+ element = @xml.create_element(name.to_s)
83
+ if xmlns = attributes.delete(:xmlns)
84
+ element.default_namespace = xmlns
85
+ end
86
+ attributes.each { |k, v| element[k.to_s] = v }
87
+ element.content = content.to_s unless content.nil?
88
+ block.call(element) if block_given?
89
+ element
90
+ end
91
+ end # module Nokogiri
92
+ end # class Writer
93
+ end # module RDF::TriX
@@ -0,0 +1,93 @@
1
+ module RDF::TriX
2
+ class Writer < RDF::Writer
3
+ ##
4
+ # REXML implementation of the TriX writer.
5
+ #
6
+ # @see http://www.germane-software.com/software/rexml/
7
+ module REXML
8
+ ##
9
+ # Returns the name of the underlying XML library.
10
+ #
11
+ # @return [Symbol]
12
+ def self.library
13
+ :rexml
14
+ end
15
+
16
+ ##
17
+ # Initializes the underlying XML library.
18
+ #
19
+ # @param [Hash{Symbol => Object}] options
20
+ # @return [void]
21
+ def initialize_xml(options = {})
22
+ require 'rexml/document' unless defined?(::REXML)
23
+ @xml = ::REXML::Document.new(nil, :attribute_quote => :quote)
24
+ @xml << ::REXML::XMLDecl.new(::REXML::XMLDecl::DEFAULT_VERSION, @encoding)
25
+ end
26
+
27
+ ##
28
+ # Generates the TriX root element.
29
+ #
30
+ # @return [void]
31
+ def write_prologue
32
+ @trix = @xml.add_element('TriX', 'xmlns' => Format::XMLNS)
33
+ end
34
+
35
+ ##
36
+ # Outputs the TriX document.
37
+ #
38
+ # @return [void]
39
+ def write_epilogue
40
+ formatter = ::REXML::Formatters::Pretty.new((@options[:indent] || 2).to_i, false)
41
+ formatter.compact = true
42
+ formatter.write(@xml, @output)
43
+ puts # add a line break after the last line
44
+ @xml = @trix = nil
45
+ end
46
+
47
+ ##
48
+ # Creates an XML graph element with the given `name`.
49
+ #
50
+ # @param [RDF::Resource] name
51
+ # @yield [element]
52
+ # @yieldparam [REXML::Element] element
53
+ # @return [REXML::Element]
54
+ def create_graph(name = nil, &block)
55
+ graph = @trix.add_element('graph')
56
+ case name
57
+ when nil then nil
58
+ when RDF::Node then graph.add_element('id').text = name.to_s # non-standard
59
+ else graph.add_element('uri').text = name.to_s
60
+ end
61
+ block.call(graph) if block_given?
62
+ graph
63
+ end
64
+
65
+ ##
66
+ # Creates an XML comment element with the given `text`.
67
+ #
68
+ # @param [String, #to_s] text
69
+ # @return [REXML::Comment]
70
+ def create_comment(text)
71
+ ::REXML::Comment.new(text.to_s)
72
+ end
73
+
74
+ ##
75
+ # Creates an XML element of the given `name`, with optional given
76
+ # `content` and `attributes`.
77
+ #
78
+ # @param [Symbol, String, #to_s] name
79
+ # @param [String, #to_s] content
80
+ # @param [Hash{Symbol => Object}] attributes
81
+ # @yield [element]
82
+ # @yieldparam [REXML::Element] element
83
+ # @return [REXML::Element]
84
+ def create_element(name, content = nil, attributes = {}, &block)
85
+ element = ::REXML::Element.new(name.to_s, nil, @xml.context)
86
+ attributes.each { |k, v| element.add_attribute(k.to_s, v) }
87
+ element.text = content.to_s unless content.nil?
88
+ block.call(element) if block_given?
89
+ element
90
+ end
91
+ end # module REXML
92
+ end # class Writer
93
+ end # module RDF::TriX
metadata ADDED
@@ -0,0 +1,175 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rdf-trix
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 2
8
+ - 0
9
+ version: 0.2.0
10
+ platform: ruby
11
+ authors:
12
+ - Arto Bendiken
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-06-22 00:00:00 +02:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rdf
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ - 2
30
+ - 0
31
+ version: 0.2.0
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: rexml
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 3
43
+ - 1
44
+ - 7
45
+ version: 3.1.7
46
+ type: :development
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: libxml-ruby
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ segments:
56
+ - 1
57
+ - 1
58
+ - 4
59
+ version: 1.1.4
60
+ type: :development
61
+ version_requirements: *id003
62
+ - !ruby/object:Gem::Dependency
63
+ name: nokogiri
64
+ prerelease: false
65
+ requirement: &id004 !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ segments:
70
+ - 1
71
+ - 4
72
+ - 2
73
+ version: 1.4.2
74
+ type: :development
75
+ version_requirements: *id004
76
+ - !ruby/object:Gem::Dependency
77
+ name: yard
78
+ prerelease: false
79
+ requirement: &id005 !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ segments:
84
+ - 0
85
+ - 5
86
+ - 6
87
+ version: 0.5.6
88
+ type: :development
89
+ version_requirements: *id005
90
+ - !ruby/object:Gem::Dependency
91
+ name: rspec
92
+ prerelease: false
93
+ requirement: &id006 !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ segments:
98
+ - 1
99
+ - 3
100
+ - 0
101
+ version: 1.3.0
102
+ type: :development
103
+ version_requirements: *id006
104
+ - !ruby/object:Gem::Dependency
105
+ name: rdf-spec
106
+ prerelease: false
107
+ requirement: &id007 !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ~>
110
+ - !ruby/object:Gem::Version
111
+ segments:
112
+ - 0
113
+ - 2
114
+ - 0
115
+ version: 0.2.0
116
+ type: :development
117
+ version_requirements: *id007
118
+ description: RDF.rb plugin for parsing/serializing TriX data.
119
+ email: public-rdf-ruby@w3.org
120
+ executables: []
121
+
122
+ extensions: []
123
+
124
+ extra_rdoc_files: []
125
+
126
+ files:
127
+ - AUTHORS
128
+ - README
129
+ - UNLICENSE
130
+ - VERSION
131
+ - etc/doap.xml
132
+ - lib/rdf/trix/format.rb
133
+ - lib/rdf/trix/reader/libxml.rb
134
+ - lib/rdf/trix/reader/nokogiri.rb
135
+ - lib/rdf/trix/reader/rexml.rb
136
+ - lib/rdf/trix/reader.rb
137
+ - lib/rdf/trix/version.rb
138
+ - lib/rdf/trix/writer/nokogiri.rb
139
+ - lib/rdf/trix/writer/rexml.rb
140
+ - lib/rdf/trix/writer.rb
141
+ - lib/rdf/trix.rb
142
+ has_rdoc: false
143
+ homepage: http://rdf.rubyforge.org/trix/
144
+ licenses:
145
+ - Public Domain
146
+ post_install_message:
147
+ rdoc_options: []
148
+
149
+ require_paths:
150
+ - lib
151
+ required_ruby_version: !ruby/object:Gem::Requirement
152
+ requirements:
153
+ - - ">="
154
+ - !ruby/object:Gem::Version
155
+ segments:
156
+ - 1
157
+ - 8
158
+ - 1
159
+ version: 1.8.1
160
+ required_rubygems_version: !ruby/object:Gem::Requirement
161
+ requirements:
162
+ - - ">="
163
+ - !ruby/object:Gem::Version
164
+ segments:
165
+ - 0
166
+ version: "0"
167
+ requirements:
168
+ - REXML (>= 3.1.7), LibXML-Ruby (>= 1.1.4) or Nokogiri (>= 1.4.2)
169
+ rubyforge_project: rdf
170
+ rubygems_version: 1.3.6
171
+ signing_key:
172
+ specification_version: 3
173
+ summary: TriX support for RDF.rb.
174
+ test_files: []
175
+