rdf-xml 0.0.3

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