rdf-trix 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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
+