rdf-xml 0.0.3

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.
File without changes
@@ -0,0 +1,25 @@
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, contact Alex Serebryakov [serebryakov@gmail.com]
25
+ or visit <http://unlicense.org/>
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.3
@@ -0,0 +1,34 @@
1
+ module RDF
2
+ ##
3
+ # **`RDF::XML`** is an XML plugin for RDF.rb.
4
+ #
5
+ # @example Requiring the `RDF::XML` module
6
+ # require 'rdf-xml'
7
+ #
8
+ # @example Parsing RDF statements from an XML file
9
+ # RDF::XML::Reader.open("etc/doap.xml") do |reader|
10
+ # reader.each_statement do |statement|
11
+ # puts statement.inspect
12
+ # end
13
+ # end
14
+ #
15
+ # @example Serializing RDF statements into an XML file
16
+ # RDF::XML::Writer.open("etc/test.xml") do |writer|
17
+ # reader.each_statement do |statement|
18
+ # writer << statement
19
+ # end
20
+ # end
21
+ #
22
+ # @see http://rdf.rubyforge.org/
23
+ #
24
+ # @author [Alex Serebryakov](http://42cities.com/)
25
+ module XML
26
+ require 'rdf'
27
+ require 'xml/format'
28
+ require 'nokogiri'
29
+
30
+ autoload :Reader, 'xml/reader'
31
+ autoload :Writer, 'xml/writer'
32
+ autoload :VERSION, 'xml/version'
33
+ end # module XML
34
+ end # module RDF
@@ -0,0 +1,20 @@
1
+ module RDF::XML
2
+ ##
3
+ # XML format specification.
4
+ #
5
+ # @example Obtaining an XML format class
6
+ # RDF::Format.for(:xml) #=> RDF::XML::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/rdf+xml")
11
+ #
12
+ class Format < RDF::Format
13
+ content_type 'application/rdf+xml', :extension => :xml
14
+ content_encoding 'utf-8'
15
+
16
+ reader { RDF::XML::Reader }
17
+ writer { RDF::XML::Writer }
18
+
19
+ end # class Format
20
+ end # module RDF::XML
@@ -0,0 +1,205 @@
1
+ module RDF
2
+ module XML
3
+ class Reader < RDF::Reader
4
+
5
+ format RDF::XML::Format
6
+
7
+ ##
8
+ # [-]
9
+ ##
10
+ def initialize(input = $stdin, options = {}, &block)
11
+ @input = input.respond_to?(:read) ? input.read : input
12
+ @xml = ::Nokogiri::XML(@input)
13
+ yield self if block_given?
14
+ end
15
+
16
+ ##
17
+ # [-]
18
+ ##
19
+ def each_triple(&block)
20
+ return unless block_given?
21
+ if @xml.root.nil?
22
+ raise RuntimeError, 'Malformed XML document'
23
+ end
24
+ @xml.root.subnodes.each do |node|
25
+ parse_descriptions(node, &block)
26
+ end
27
+ end
28
+
29
+ ##
30
+ # [-]
31
+ ##
32
+ def each_statement(&block)
33
+ return unless block_given?
34
+ each_triple do |*triple|
35
+ yield RDF::Statement.new(*triple)
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ ##
42
+ # [-]
43
+ ##
44
+ def parse_descriptions(element, parent = nil, predicate = nil, &block)
45
+
46
+ # Parsing all inline properties
47
+ properties = Hash[parse_inline_properties(element)]
48
+ # Checking if this is a blank node
49
+ uri = properties.key?(:uri) ? properties.delete(:uri) : RDF::Node.uuid
50
+
51
+ # If parent is present, yield the relationship
52
+ unless parent.nil?
53
+ block.call([parent, predicate, uri])
54
+ end
55
+
56
+ # Yield each nested property
57
+ properties.each do |name, value|
58
+ block.call([uri, name, value])
59
+ end
60
+
61
+ # Yield RDF type, if tag name is not RDF.description
62
+ if element.ns_name != RDF.Description
63
+ block.call([uri, RDF.type, element.ns_name])
64
+ end
65
+
66
+ parse_all_nested_properties(element, uri, &block)
67
+ end
68
+
69
+ ##
70
+ # [-]
71
+ ##
72
+ def parse_all_nested_properties(element, parent, &block)
73
+ element.subnodes.each do |node|
74
+ parse_nested_property(node, parent, &block)
75
+ end
76
+ end
77
+
78
+ ##
79
+ # [-]
80
+ ##
81
+ def property_has_node_id?(element)
82
+ att = element.attribute_with_ns('nodeID', RDF.to_uri.to_s)
83
+ att.nil? ? nil : RDF::Node.new(att.value)
84
+ end
85
+
86
+ ##
87
+ # [-]
88
+ ##
89
+ def property_has_resource?(element)
90
+ att = element.attribute_with_ns('resource', RDF.to_uri.to_s)
91
+ att.nil? ? nil : RDF::URI.new(element.base || uri).join(att.value)
92
+ end
93
+
94
+ # Checks if rdf:parseType is set to 'Resource'
95
+ # <ex:editor rdf:parseType="Resource">
96
+ # <ex:fullName>Dave Beckett</ex:fullName>
97
+ # <ex:homePage rdf:resource="http://purl.org/net/dajobe/"/>
98
+ # </ex:editor>
99
+ def property_is_resource_parse_type?(element, parent, &block)
100
+ att = element.attribute_with_ns('parseType', RDF.to_uri.to_s)
101
+ object = att.nil? ? nil : (att.value == 'Resource' ? RDF::Node.uuid : nil)
102
+ return nil if object.nil?
103
+ parse_all_nested_properties(element, object, &block)
104
+ block.call([parent, element.ns_name, object])
105
+ true
106
+ end
107
+
108
+ ##
109
+ # [-]
110
+ ##
111
+ def property_is_resource?(element, parent, &block)
112
+ object = (property_has_node_id?(element) or property_has_resource?(element))
113
+ return nil if object.nil?
114
+ block.call([parent, element.ns_name, object])
115
+ true
116
+ end
117
+
118
+ # Checks if rdf:parseType is set to 'Literal'
119
+ # <ex:editor rdf:parseType="Literal">
120
+ # <html><head><title>Hello, world!</title></head></html>
121
+ # </ex:editor>
122
+ def property_is_literal_parse_type?(element, parent, &block)
123
+ att = element.attribute_with_ns('parseType', RDF.to_uri.to_s)
124
+ object = att.nil? ? nil : (att.value == 'Literal' ? true : nil)
125
+ return nil if object.nil?
126
+ block.call([parent, element.ns_name, element.to_s])
127
+ true
128
+ end
129
+
130
+ ##
131
+ # [-]
132
+ ##
133
+ def property_has_subnodes?(element, parent, &block)
134
+ return nil if element.subnodes.empty?
135
+ element.subnodes.each do |child|
136
+ parse_descriptions(child, parent, element.ns_name, &block)
137
+ end
138
+ end
139
+
140
+ ##
141
+ # [-]
142
+ ##
143
+ def parse_nested_property(element, parent, &block)
144
+ return if property_is_resource?(element, parent, &block)
145
+ return if property_is_resource_parse_type?(element, parent, &block)
146
+ return if property_is_literal_parse_type?(element, parent, &block)
147
+ return if property_has_subnodes?(element, parent, &block)
148
+
149
+ # Checks if property has xml:lang
150
+ att = element.attribute_with_ns('lang', 'http://www.w3.org/XML/1998/namespacelang')
151
+ language = (att.nil? ? nil : att.value)
152
+
153
+ # Checks if property has rdf:datatype
154
+ att = element.attribute_with_ns('datatype', RDF.to_uri.to_s)
155
+ datatype = (att.nil? ? nil : att.value)
156
+
157
+ object = RDF::Literal.new(element.content, {
158
+ :datatype => datatype,
159
+ :language => language })
160
+
161
+ block.call([parent, element.ns_name, object])
162
+
163
+ end
164
+
165
+ ##
166
+ # [-]
167
+ ##
168
+ def parse_inline_properties(element)
169
+ element.attributes.values.map do |att|
170
+ case att.ns_name
171
+ when RDF.about then [:uri, RDF::URI.new(element.base || uri).join(att.value)]
172
+ when RDF.ID then [:uri, RDF::URI.new(element.base || att.value).join(att.value)]
173
+ when RDF.nodeID then [:uri, RDF::Node.new(att.value)]
174
+ else [att.ns_name, att.value]
175
+ end
176
+ end
177
+ end
178
+
179
+ end # Reader
180
+ end # XML
181
+ end # RDF
182
+
183
+
184
+ module Nokogiri
185
+ module Common
186
+ def ns_name
187
+ RDF::URI.new((namespace.nil? ? '' : namespace.href) + name)
188
+ end
189
+ end
190
+ module XML
191
+ class Attr
192
+ include Nokogiri::Common
193
+ end
194
+ class Element
195
+ include Nokogiri::Common
196
+ def base
197
+ att = document.root.attributes['base']
198
+ att.nil? ? '' : att.value
199
+ end
200
+ def subnodes
201
+ children.reject { |child| child.text? }
202
+ end
203
+ end
204
+ end
205
+ end
@@ -0,0 +1,25 @@
1
+ module RDF
2
+ module XML
3
+ module VERSION
4
+ MAJOR = 0
5
+ MINOR = 0
6
+ TINY = 3
7
+ EXTRA = nil
8
+
9
+ STRING = [MAJOR, MINOR, TINY].join('.')
10
+ STRING << "-#{EXTRA}" if EXTRA
11
+
12
+ ##
13
+ # @return [String]
14
+ def self.to_s() STRING end
15
+
16
+ ##
17
+ # @return [String]
18
+ def self.to_str() STRING end
19
+
20
+ ##
21
+ # @return [Array(Integer, Integer, Integer)]
22
+ def self.to_a() [MAJOR, MINOR, TINY] end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,181 @@
1
+ module RDF
2
+ module XML
3
+ class Writer < RDF::Writer
4
+
5
+ format RDF::XML::Format
6
+
7
+ ##
8
+ # [-]
9
+ ##
10
+ def initialize(output = $stdout, options = {}, &block)
11
+ @output, @options = output, options
12
+ @nodes = {}
13
+ @base = nil
14
+ @namespaces = { :rdf => RDF.to_uri.to_s }
15
+
16
+ if block_given?
17
+ yield self
18
+ write_prologue unless @options[:declaration] == false
19
+ write_document
20
+ write_epilogue unless @options[:declaration] == false
21
+ end
22
+ end
23
+
24
+ ##
25
+ # [-]
26
+ ##
27
+ def write_prologue
28
+
29
+ ns = @namespaces.map do |short, uri|
30
+ ' xmlns:%s="%s"' % [short, uri]
31
+ end.join('')
32
+
33
+ unless @base.nil?
34
+ bs = ' xml:base="%s"' % @base
35
+ end
36
+
37
+ puts ("<?xml version='1.0' encoding='utf-8'?><rdf:RDF %s %s>" % [ns, bs], false)
38
+ end
39
+
40
+ def write_epilogue
41
+ puts "</rdf:RDF>"
42
+ end
43
+
44
+ ##
45
+ # [-]
46
+ ##
47
+ def write_document
48
+ @nodes.each do |id, atts|
49
+ puts format_description(id, atts)
50
+ end
51
+ end
52
+
53
+ ##
54
+ # [-]
55
+ ##
56
+ def write_triple(subject, predicate, object)
57
+ s = subject.to_s
58
+ p = predicate.to_s
59
+ @nodes[s] ||= {}
60
+ @nodes[s][p] ||= []
61
+ @nodes[s][p] << object
62
+ end
63
+
64
+ ##
65
+ # [-]
66
+ ##
67
+ def namespace!(uri, short)
68
+ @namespaces[short.to_s.to_sym] = uri.to_s
69
+ end
70
+
71
+ ##
72
+ # [-]
73
+ ##
74
+ def base!(uri)
75
+ @base = uri.to_s
76
+ end
77
+
78
+ private
79
+
80
+
81
+ ##
82
+ # [-]
83
+ ##
84
+ def format_description(id, atts)
85
+ tag = format_tag_name(atts)
86
+ contents = format_attributes(atts)
87
+ about = ' rdf:about="%s"' % id
88
+ "<%s%s>%s</%s>" % [tag, about, contents, tag]
89
+ end
90
+
91
+ ##
92
+ # [-]
93
+ ##
94
+ def format_tag_name(atts)
95
+ if atts.key?(RDF.type.to_s)
96
+ atts.delete(RDF.type.to_s).first
97
+ else
98
+ "rdf:Description"
99
+ end
100
+ end
101
+
102
+ ##
103
+ # [-]
104
+ ##
105
+ def format_attributes(atts)
106
+ atts.map do |predicate, values|
107
+ values.map do |value|
108
+ format_attribute(predicate, value)
109
+ end.join('')
110
+ end.join('')
111
+ end
112
+
113
+ ##
114
+ # [-]
115
+ ##
116
+ def format_attribute(predicate, value)
117
+ if value.kind_of? RDF::Resource
118
+ format_resource_att(predicate, value)
119
+ elsif value.kind_of? Literal
120
+ format_literal_att(predicate, value)
121
+ end
122
+ end
123
+
124
+ ##
125
+ # [-]
126
+ ##
127
+ def format_resource_att(predicate, value)
128
+ '<%s rdf:resource="%s" />' % [predicate, value.to_s]
129
+ end
130
+
131
+ ##
132
+ # [-]
133
+ ##
134
+ def format_literal_att(predicate, value)
135
+ extra = ""
136
+ if value.has_datatype?
137
+ extra += ' rdf:datatype="%s"' % value.datatype.to_s
138
+ end
139
+ if value.has_language?
140
+ extra += ' xml:lang="%s"' % value.language.to_s
141
+ end
142
+ if value.kind_of? RDF::Literal
143
+ value = value.object
144
+ end
145
+ '<%s%s>%s</%s>' % [predicate, extra, value, predicate]
146
+ end
147
+
148
+ ##
149
+ # [-]
150
+ ##
151
+ def adjust_ns(string)
152
+ @namespaces.each do |short, uri|
153
+ string = string.gsub(uri, "%s:" % short)
154
+ end
155
+ string
156
+ end
157
+
158
+ ##
159
+ # [-]
160
+ ##
161
+ def adjust_base(string)
162
+ unless @base.nil?
163
+ string = string.gsub(@base, '')
164
+ end
165
+ string
166
+ end
167
+
168
+ ##
169
+ # [-]
170
+ ##
171
+ def puts(string, adjust = true)
172
+ if adjust
173
+ string = adjust_ns(string)
174
+ string = adjust_base(string)
175
+ end
176
+ @output.puts(string)
177
+ end
178
+
179
+ end # Writer
180
+ end # XML
181
+ end # RDF
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rdf-xml
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 3
9
+ version: 0.0.3
10
+ platform: ruby
11
+ authors:
12
+ - Alex Serebryakov
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-05-26 00:00:00 +01:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rspec
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 1
29
+ - 3
30
+ - 0
31
+ version: 1.3.0
32
+ type: :development
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: rdf
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ - 1
44
+ - 1
45
+ version: 0.1.1
46
+ type: :runtime
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: nokogiri
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ segments:
56
+ - 1
57
+ - 4
58
+ - 1
59
+ version: 1.4.1
60
+ type: :runtime
61
+ version_requirements: *id003
62
+ description: An RDF.rb plugin for XML files.
63
+ email: serebryakov@gmail.com
64
+ executables: []
65
+
66
+ extensions: []
67
+
68
+ extra_rdoc_files: []
69
+
70
+ files:
71
+ - README.rdoc
72
+ - UNLICENSE
73
+ - VERSION
74
+ - lib/rdf-xml.rb
75
+ - lib/xml/format.rb
76
+ - lib/xml/reader.rb
77
+ - lib/xml/version.rb
78
+ - lib/xml/writer.rb
79
+ has_rdoc: true
80
+ homepage: http://github.com/42cities/rdf-xml/
81
+ licenses: []
82
+
83
+ post_install_message:
84
+ rdoc_options: []
85
+
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ segments:
93
+ - 0
94
+ version: "0"
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ segments:
100
+ - 0
101
+ version: "0"
102
+ requirements: []
103
+
104
+ rubyforge_project: rdf-xml
105
+ rubygems_version: 1.3.6
106
+ signing_key:
107
+ specification_version: 3
108
+ summary: An RDF.rb plugin for XML files.
109
+ test_files: []
110
+