xmlcodec 0.3.1 → 0.3.2

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/Rakefile CHANGED
@@ -105,13 +105,17 @@ end
105
105
  #############################################################################
106
106
 
107
107
  desc "git tag, build and release gem"
108
- task :release => :build do
109
- unless `git branch` =~ /^\* master$/
110
- puts "You must be on the master branch to release!"
111
- exit!
108
+ task :release => :build do |t|
109
+ if not File.exists? "pkg/tag-#{version}"
110
+ unless `git branch` =~ /^\* master$/
111
+ puts "You must be on the master branch to release!"
112
+ exit!
113
+ end
114
+ sh "git commit --allow-empty -a -m 'Release #{version}'"
115
+ sh "git tag v#{version}"
116
+ sh "touch pkg/tag-#{version}"
112
117
  end
113
- sh "git commit --allow-empty -a -m 'Release #{version}'"
114
- sh "git tag v#{version}"
118
+
115
119
  sh "git push origin master"
116
120
  sh "git push origin v#{version}"
117
121
  sh "gem push pkg/#{name}-#{version}.gem"
@@ -34,177 +34,6 @@ module XMLCodec
34
34
  ## A xmlsubel is any subelement of a given element
35
35
 
36
36
  private
37
- # Class level variable to hold the list of subelements
38
- def self.xmlsubels
39
- @xmlsubels ||=[]
40
- end
41
-
42
- # Class level variable to hold the list of subelements that are multiple
43
- def self.xmlsubelmultiples
44
- @xmlsubelmultiples ||=[]
45
- end
46
-
47
- # Class level variable that holds the list of attributes
48
- def self.xmlattrs
49
- @xmlattrs ||=[]
50
- end
51
-
52
- # Add a name as being a subelement (mult or single)
53
- def self._xmlsubel(name)
54
- self.xmlsubels << name
55
- end
56
-
57
- # Add a xmlsubel type attribute
58
- def self.xmlsubel(name) #:doc:
59
- name = name.to_sym
60
- self._xmlsubel(name)
61
- attr_reader name
62
- define_method((name.to_s+"=").to_sym) { |value|
63
- if value.is_a? String or value.is_a? Fixnum
64
- value = self.class.get_element_class(name).new(value)
65
- end
66
- value.__parent = self if value
67
- instance_variable_set "@#{name}", value
68
- }
69
- end
70
-
71
- # Add a xmlsubel_mult type attribute (wrapper around attr_accessor)
72
- def self.xmlsubel_mult(name) #:doc:
73
- name = name.to_sym
74
- self._xmlsubel(name)
75
- self.xmlsubelmultiples << name
76
- define_method(name){
77
- if not self.instance_variables.index("@#{name}".to_sym)
78
- instance_variable_set "@#{name}", XMLSubElements.new(self)
79
- end
80
- instance_variable_get "@#{name}"
81
- }
82
- end
83
-
84
- # Iterates over the object's XML subelements
85
- def self.each_subel
86
- if not self.instance_variables.index("@__subel_names".to_sym)
87
- names = []
88
- # Iterate all the superclasses that are still children of XMLElement
89
- # and iterate each of the subelements
90
- c = self
91
- while c.ancestors.index(XMLCodec::XMLElement)
92
- names += c.xmlsubels
93
- c = c.superclass
94
- end
95
- @__subel_names = names
96
- end
97
- @__subel_names.each {|name| yield name}
98
- end
99
-
100
- # Iterate all the superclasses that are still children of XMLElement
101
- # and check if any of them have the subelement mult defined
102
- def self.subel_mult?(element)
103
- if not self.instance_variables.index("@__subel_mult_names".to_sym)
104
- names = []
105
- c = self
106
- while c.ancestors.index(XMLCodec::XMLElement)
107
- names += c.xmlsubelmultiples
108
- c = c.superclass
109
- end
110
- @__subel_mult_names = names
111
- end
112
- return @__subel_mult_names.index(element)? true : false
113
- end
114
-
115
- # Iterate all the superclasses that are still children of XMLElement
116
- # and check if any of them have any subelements handled by this class
117
- def get_subel(elclass)
118
- names = elclass.get_elnames
119
- c = self.class
120
- while c.ancestors.index(XMLCodec::XMLElement)
121
- names.each do |name|
122
- if c.xmlsubels.index(name.to_sym)
123
- return names[0].to_sym
124
- end
125
- end
126
- c = c.superclass
127
- end
128
- return nil
129
- end
130
-
131
- # Iterates over the object's XML atributes
132
- def self.each_attr
133
- attr_names.each {|name| yield name}
134
- end
135
-
136
- def self.attr_names
137
- if not self.instance_variables.index("@__attr_names".to_sym)
138
- names = []
139
- # Iterate all the superclasses that are still children of XMLElement
140
- # and iterate each of the attributes
141
- c = self
142
- while c.ancestors.index(XMLCodec::XMLElement)
143
- names += c.xmlattrs
144
- c = c.superclass
145
- end
146
- @__attr_names = names
147
- end
148
-
149
- @__attr_names
150
- end
151
-
152
- # Creates the XML for the atributes
153
- def create_xml_attr(parent)
154
- self.class.each_attr do |a|
155
- value = self.send(a)
156
- if value
157
- parent.set_attribute(a.to_s, value)
158
- end
159
- end
160
- end
161
-
162
- # returns a string with the opening tag for the element
163
- def create_open_tag
164
- attrs = {}
165
- self.class.each_attr do |a|
166
- value = self.send(a)
167
- if value
168
- attrs[a.to_s] = value
169
- end
170
- end
171
- XMLCodec::XMLUtils::create_open_tag(elname.to_s, attrs)
172
- end
173
-
174
- # returns a string with the closing tag for the element
175
- def create_close_tag
176
- XMLCodec::XMLUtils::create_close_tag(elname.to_s)
177
- end
178
-
179
- # Declare the class as having many subelements. Instances will have a
180
- # method called #subelements that will return an instance of XMLSubElements
181
- def self.xmlsubelements #:doc:
182
- define_method(:subelements) {
183
- @subelements ||= XMLSubElements.new(self)
184
- }
185
- define_method('<<') {|value|
186
- subelements << value
187
- }
188
- define_method(:find_first_named) {|name|
189
- subelements.find_first_named(name)
190
- }
191
- define_method('[]') {|name|
192
- subelements.find_first_named(name)
193
- }
194
- define_method(:find_all_named) {|name|
195
- subelements.find_all_named(name)
196
- }
197
- self.class_eval do
198
- def self.has_subelements?; true; end
199
- end
200
- end
201
-
202
- # Add a xmlattr type attribute (wrapper around attr_accessor)
203
- def self.xmlattr(name) #:doc:
204
- self.xmlattrs << name.to_sym
205
- attr_accessor name
206
- end
207
-
208
37
  # Defines a new xml format (like XHTML or DocBook). This should be used in
209
38
  # a class that's the super class of all the elements of a format
210
39
  def self.xmlformat(name=nil)
@@ -238,48 +67,6 @@ module XMLCodec
238
67
  def self.get_elnames
239
68
  @elnames||=[]
240
69
  end
241
-
242
- # Set the element as having a value. The element will have an initializer
243
- # that takes a value as argument and an accessor named #value. This should
244
- # be used for elements that contain only text and no subelements
245
- def self.elwithvalue
246
- self.class_eval do
247
- def self.hasvalue?; true; end
248
- end
249
- self.class_eval do
250
- def initialize(value=nil)
251
- @value = value
252
- end
253
- end
254
- attr_accessor :value
255
- end
256
-
257
- # Set the element as having a value that eats up any subelements as if they
258
- # were text. The element will behave similarly to "elwithvalue" with an
259
- # initializar that takes a value as argument and an accessor named #value
260
- # and will consume all its subelements as if they were text. This should
261
- # be used for elements that contain subelements that you want to treat as
262
- # text like <content> in Atom
263
- def self.elallvalue
264
- self.elwithvalue
265
- self.class_eval do
266
- def self.allvalue?; true; end
267
- end
268
- end
269
-
270
- # Creates the XML subelements
271
- def create_xml_subel(parent)
272
- self.class.each_subel do |a|
273
- if value = self.send(a)
274
- value.create_xml(parent)
275
- end
276
- end
277
- end
278
-
279
- # Create the XML of the SubElements
280
- def create_xml_subelements(parent)
281
- self.subelements.create_xml(parent)
282
- end
283
70
 
284
71
  # Which level of indentation are we in?
285
72
  #
@@ -361,236 +148,5 @@ module XMLCodec
361
148
  def self.get_element_names(name)
362
149
  get_element_class(name).get_elnames
363
150
  end
364
-
365
- # Method that checks if a given class has subelements. This is usually only
366
- # used when exporting stuff.
367
- def self.has_subelements?; false end
368
- def has_subelements?; self.class.has_subelements? end
369
-
370
- # tests if the element is a value element as defined by 'elwithvalue'
371
- def self.hasvalue?; false end
372
- def hasvalue?; self.class.hasvalue? end
373
-
374
- # tests if the element is a value element as defined by 'elallvalue'
375
- def self.allvalue?; false end
376
- def allvalue?; self.class.allvalue?; end
377
-
378
- # Creates the xml for the element inside the parent element. The parent
379
- # passed should be a Nokogiri XML Node or Document. This call is recursive
380
- # creating the XML for any subelements.
381
- def create_xml(parent)
382
- xmlel = parent.add_child Nokogiri::XML::Element.new(self.elname.to_s, parent)
383
- if self.hasvalue?
384
- xmlel.add_child self.value
385
- end
386
- create_xml_attr(xmlel)
387
- create_xml_subel(xmlel)
388
-
389
- if self.has_subelements?
390
- create_xml_subelements(xmlel)
391
- end
392
-
393
- xmlel
394
- end
395
-
396
- # Import the XML into an object from a Nokogiri XML Node or Document or from
397
- # a string.
398
- def self.import_xml(obj)
399
- if obj.instance_of? String
400
- _import_xml_text(obj)
401
- elsif obj.instance_of? Nokogiri::XML::Node or
402
- obj.instance_of? Nokogiri::XML::Document
403
- _import_xml_dom(obj)
404
- else
405
- nil
406
- end
407
- end
408
-
409
- # Import the XML into an object from a Nokogiri XML Node or Document.
410
- # This call is recursive and imports any subelements found into the
411
- # corresponding objects.
412
- def self._import_xml_dom(xmlel)
413
- if xmlel.is_a? Nokogiri::XML::Document
414
- xmlel = xmlel.root
415
- end
416
-
417
- elclass = get_element_class(xmlel.name)
418
- if not elclass
419
- if class_variable_get(:@@strict_parsing)
420
- raise ElementClassNotFound, "No class defined for element type: '#{e.name}'"
421
- else
422
- return nil
423
- end
424
- end
425
-
426
- if elclass.allvalue?
427
- elements = [xmlel.children.map{|c| c.to_xml(:save_with=>0)}.join]
428
- else
429
- elements = []
430
- xmlel.children.each do |e|
431
- if e.text?
432
- elements << e.text
433
- else
434
- element = _import_xml_dom(e)
435
- elements << element if element
436
- end
437
- end
438
- end
439
-
440
- attributes = {}
441
- xmlel.attributes.each do |name, attr|
442
- attributes[name] = attr.value
443
- end
444
-
445
- elclass.new_with_content(attributes, elements)
446
- end
447
-
448
- # Import the XML directly from the text.
449
- def self._import_xml_text(text)
450
- parser = XMLStreamObjectParser.new(self)
451
- parser.parse(text)
452
- parser.top_element
453
- end
454
-
455
- # Create a new element passing it all the atributes, children and texts
456
- def self.new_with_content(attrs, children)
457
- text_children = []
458
- element_children = []
459
-
460
- children.each do |c|
461
- if c.is_a? String
462
- text_children << c
463
- else
464
- element_children << c
465
- end
466
- end
467
-
468
- obj = self.allocate
469
- obj.add_attr(attrs)
470
- obj.add_subel(element_children)
471
- obj.add_texts(text_children)
472
- if obj.has_subelements?
473
- obj.add_subelements(children)
474
- end
475
- obj
476
- end
477
-
478
- # add the attributes passed as a hash to the element
479
- def add_attr(attrs)
480
- attrs.each do |name, value|
481
- if not self.class.attr_names.include?(name.to_sym)
482
- if self.class.class_variable_get(:@@strict_parsing)
483
- raise ElementAttributeNotFound, "No attribute '#{name}' defined for class '#{self.class}'"
484
- end
485
- else
486
- self.send("#{name}=", value)
487
- end
488
- end
489
- end
490
-
491
- # add the text elements into the element
492
- def add_texts(texts)
493
- if self.hasvalue?
494
- @value = texts.join
495
- end
496
- end
497
-
498
- # add the subelements into the element
499
- def add_subel(children)
500
- children.each do |c|
501
- if subel_name = get_subel(c.class)
502
- if self.class.subel_mult? subel_name
503
- self.send(subel_name) << c
504
- else
505
- self.send(subel_name.to_s+'=', c)
506
- end
507
- end
508
- end
509
- end
510
-
511
- # If the class is one with many subelements import all of them into the
512
- # object.
513
- def add_subelements(all_children)
514
- all_children.each {|c| self.subelements << c}
515
- end
516
-
517
-
518
- # create the XML text of the element
519
- def xml_text
520
- str = create_open_tag
521
- if self.hasvalue?
522
- str << XMLCodec::XMLUtils::escape_xml(self.value)
523
- end
524
-
525
- each_subelement do |e|
526
- str << e.xml_text
527
- end
528
-
529
- str << create_close_tag
530
- str
531
- end
532
-
533
- # Have we already started the partial export of this element?
534
- def already_partial_exported?
535
- (@already_partial_exported ||= false)
536
- end
537
-
538
- # Have we already ended the partial export of this element?
539
- def already_partial_export_ended?
540
- (@already_partial_export_ended ||= false)
541
- end
542
-
543
- # Export this element into a file. Will also start to export the parents of
544
- # the element. It's equivalent to calling start_partial_export followed by
545
- # end_partial_export.
546
- def partial_export(file)
547
- if not already_partial_exported?
548
- start_partial_export(file)
549
- end_partial_export(file)
550
- end
551
- end
552
-
553
- # Starts to export the element to a file. all the existing elements will be
554
- # exported. After calling this you should only add stuff that you will
555
- # export explicitly by calling partial_export or start_partial_export.
556
- def start_partial_export(file)
557
- if not already_partial_exported?
558
- @already_partial_exported = true
559
- if self.__parent
560
- self.__parent.start_partial_export(file)
561
- end
562
-
563
- file << create_open_tag
564
- if self.hasvalue?
565
- file << XMLCodec::XMLUtils::escape_xml(self.value)
566
- end
567
-
568
- each_subelement do |e|
569
- e.partial_export(file)
570
- end
571
- end
572
- end
573
-
574
- # Ends the partial exporting of the element.
575
- def end_partial_export(file)
576
- if not already_partial_export_ended?
577
- @already_partial_export_ended = true
578
-
579
- if not already_partial_exported?
580
- raise "<#{self} Trying to end the export of an element that hasn't"+
581
- " been started yet"
582
- end
583
-
584
- each_subelement do |e|
585
- e.end_partial_export(file)
586
- end
587
-
588
- file << create_close_tag
589
-
590
- if self.__parent
591
- self.__parent.delete_element(self)
592
- end
593
- end
594
- end
595
151
  end
596
152
  end
@@ -0,0 +1,36 @@
1
+ module XMLCodec
2
+ class XMLElement
3
+ private
4
+ # Add a xmlattr type attribute (wrapper around attr_accessor)
5
+ def self.xmlattr(name) #:doc:
6
+ self.xmlattrs << name.to_sym
7
+ attr_accessor name
8
+ end
9
+
10
+ # Class level variable that holds the list of attributes
11
+ def self.xmlattrs
12
+ @xmlattrs ||=[]
13
+ end
14
+
15
+ # Iterates over the object's XML atributes
16
+ def self.each_attr
17
+ attr_names.each {|name| yield name}
18
+ end
19
+
20
+ def self.attr_names
21
+ if not self.instance_variables.index("@__attr_names".to_sym)
22
+ names = []
23
+ # Iterate all the superclasses that are still children of XMLElement
24
+ # and iterate each of the attributes
25
+ c = self
26
+ while c.ancestors.index(XMLCodec::XMLElement)
27
+ names += c.xmlattrs
28
+ c = c.superclass
29
+ end
30
+ @__attr_names = names
31
+ end
32
+
33
+ @__attr_names
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,66 @@
1
+ module XMLCodec
2
+ class XMLElement
3
+ public
4
+ # Create a new element passing it all the atributes, children and texts
5
+ def self.new_with_content(attrs, children)
6
+ text_children = []
7
+ element_children = []
8
+
9
+ children.each do |c|
10
+ if c.is_a? String
11
+ text_children << c
12
+ else
13
+ element_children << c
14
+ end
15
+ end
16
+
17
+ obj = self.allocate
18
+ obj.add_attr(attrs)
19
+ obj.add_subel(element_children)
20
+ obj.add_texts(text_children)
21
+ if obj.has_subelements?
22
+ obj.add_subelements(children)
23
+ end
24
+ obj
25
+ end
26
+
27
+ # add the attributes passed as a hash to the element
28
+ def add_attr(attrs)
29
+ attrs.each do |name, value|
30
+ if not self.class.attr_names.include?(name.to_sym)
31
+ if self.class.class_variable_get(:@@strict_parsing)
32
+ raise ElementAttributeNotFound, "No attribute '#{name}' defined for class '#{self.class}'"
33
+ end
34
+ else
35
+ self.send("#{name}=", value)
36
+ end
37
+ end
38
+ end
39
+
40
+ # add the text elements into the element
41
+ def add_texts(texts)
42
+ if self.hasvalue?
43
+ @value = texts.join
44
+ end
45
+ end
46
+
47
+ # add the subelements into the element
48
+ def add_subel(children)
49
+ children.each do |c|
50
+ if subel_name = get_subel(c.class)
51
+ if self.class.subel_mult? subel_name
52
+ self.send(subel_name) << c
53
+ else
54
+ self.send(subel_name.to_s+'=', c)
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ # If the class is one with many subelements import all of them into the
61
+ # object.
62
+ def add_subelements(all_children)
63
+ all_children.each {|c| self.subelements << c}
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,78 @@
1
+ module XMLCodec
2
+ class XMLElement
3
+ public
4
+ # Creates the xml for the element inside the parent element. The parent
5
+ # passed should be a Nokogiri XML Node or Document. This call is recursive
6
+ # creating the XML for any subelements.
7
+ def create_xml(parent)
8
+ xmlel = parent.add_child Nokogiri::XML::Element.new(self.elname.to_s, parent)
9
+ if self.hasvalue?
10
+ xmlel.add_child self.value
11
+ end
12
+ create_xml_attr(xmlel)
13
+ create_xml_subel(xmlel)
14
+
15
+ if self.has_subelements?
16
+ create_xml_subelements(xmlel)
17
+ end
18
+
19
+ xmlel
20
+ end
21
+
22
+ # Creates the XML subelements
23
+ def create_xml_subel(parent)
24
+ self.class.each_subel do |a|
25
+ if value = self.send(a)
26
+ value.create_xml(parent)
27
+ end
28
+ end
29
+ end
30
+
31
+ # Create the XML of the SubElements
32
+ def create_xml_subelements(parent)
33
+ self.subelements.create_xml(parent)
34
+ end
35
+
36
+ # Creates the XML for the atributes
37
+ def create_xml_attr(parent)
38
+ self.class.each_attr do |a|
39
+ value = self.send(a)
40
+ if value
41
+ parent.set_attribute(a.to_s, value)
42
+ end
43
+ end
44
+ end
45
+
46
+ # create the XML text of the element
47
+ def xml_text
48
+ str = create_open_tag
49
+ if self.hasvalue?
50
+ str << XMLCodec::XMLUtils::escape_xml(self.value)
51
+ end
52
+
53
+ each_subelement do |e|
54
+ str << e.xml_text
55
+ end
56
+
57
+ str << create_close_tag
58
+ str
59
+ end
60
+
61
+ # returns a string with the opening tag for the element
62
+ def create_open_tag
63
+ attrs = {}
64
+ self.class.each_attr do |a|
65
+ value = self.send(a)
66
+ if value
67
+ attrs[a.to_s] = value
68
+ end
69
+ end
70
+ XMLCodec::XMLUtils::create_open_tag(elname.to_s, attrs)
71
+ end
72
+
73
+ # returns a string with the closing tag for the element
74
+ def create_close_tag
75
+ XMLCodec::XMLUtils::create_close_tag(elname.to_s)
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,64 @@
1
+ module XMLCodec
2
+ class XMLElement
3
+ public
4
+ # Import the XML into an object from a Nokogiri XML Node or Document or from
5
+ # a string.
6
+ def self.import_xml(obj)
7
+ if obj.instance_of? String
8
+ _import_xml_text(obj)
9
+ elsif obj.instance_of? Nokogiri::XML::Node or
10
+ obj.instance_of? Nokogiri::XML::Document
11
+ _import_xml_dom(obj)
12
+ else
13
+ nil
14
+ end
15
+ end
16
+
17
+ private
18
+ # Import the XML into an object from a Nokogiri XML Node or Document.
19
+ # This call is recursive and imports any subelements found into the
20
+ # corresponding objects.
21
+ def self._import_xml_dom(xmlel)
22
+ if xmlel.is_a? Nokogiri::XML::Document
23
+ xmlel = xmlel.root
24
+ end
25
+
26
+ elclass = get_element_class(xmlel.name)
27
+ if not elclass
28
+ if class_variable_get(:@@strict_parsing)
29
+ raise ElementClassNotFound, "No class defined for element type: '#{e.name}'"
30
+ else
31
+ return nil
32
+ end
33
+ end
34
+
35
+ if elclass.allvalue?
36
+ elements = [xmlel.children.map{|c| c.to_xml(:save_with=>0)}.join]
37
+ else
38
+ elements = []
39
+ xmlel.children.each do |e|
40
+ if e.text?
41
+ elements << e.text
42
+ else
43
+ element = _import_xml_dom(e)
44
+ elements << element if element
45
+ end
46
+ end
47
+ end
48
+
49
+ attributes = {}
50
+ xmlel.attributes.each do |name, attr|
51
+ attributes[name] = attr.value
52
+ end
53
+
54
+ elclass.new_with_content(attributes, elements)
55
+ end
56
+
57
+ # Import the XML directly from the text.
58
+ def self._import_xml_text(text)
59
+ parser = XMLStreamObjectParser.new(self)
60
+ parser.parse(text)
61
+ parser.top_element
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,68 @@
1
+ module XMLCodec
2
+ class XMLElement
3
+ private
4
+ # Have we already started the partial export of this element?
5
+ def already_partial_exported?
6
+ (@already_partial_exported ||= false)
7
+ end
8
+
9
+ # Have we already ended the partial export of this element?
10
+ def already_partial_export_ended?
11
+ (@already_partial_export_ended ||= false)
12
+ end
13
+
14
+ public
15
+ # Export this element into a file. Will also start to export the parents of
16
+ # the element. It's equivalent to calling start_partial_export followed by
17
+ # end_partial_export.
18
+ def partial_export(file)
19
+ if not already_partial_exported?
20
+ start_partial_export(file)
21
+ end_partial_export(file)
22
+ end
23
+ end
24
+
25
+ # Starts to export the element to a file. all the existing elements will be
26
+ # exported. After calling this you should only add stuff that you will
27
+ # export explicitly by calling partial_export or start_partial_export.
28
+ def start_partial_export(file)
29
+ if not already_partial_exported?
30
+ @already_partial_exported = true
31
+ if self.__parent
32
+ self.__parent.start_partial_export(file)
33
+ end
34
+
35
+ file << create_open_tag
36
+ if self.hasvalue?
37
+ file << XMLCodec::XMLUtils::escape_xml(self.value)
38
+ end
39
+
40
+ each_subelement do |e|
41
+ e.partial_export(file)
42
+ end
43
+ end
44
+ end
45
+
46
+ # Ends the partial exporting of the element.
47
+ def end_partial_export(file)
48
+ if not already_partial_export_ended?
49
+ @already_partial_export_ended = true
50
+
51
+ if not already_partial_exported?
52
+ raise "<#{self} Trying to end the export of an element that hasn't"+
53
+ " been started yet"
54
+ end
55
+
56
+ each_subelement do |e|
57
+ e.end_partial_export(file)
58
+ end
59
+
60
+ file << create_close_tag
61
+
62
+ if self.__parent
63
+ self.__parent.delete_element(self)
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,93 @@
1
+ module XMLCodec
2
+ class XMLElement
3
+ private
4
+ # Add a xmlsubel type attribute
5
+ def self.xmlsubel(name) #:doc:
6
+ name = name.to_sym
7
+ self._xmlsubel(name)
8
+ attr_reader name
9
+ define_method((name.to_s+"=").to_sym) { |value|
10
+ if value.is_a? String or value.is_a? Fixnum
11
+ value = self.class.get_element_class(name).new(value)
12
+ end
13
+ value.__parent = self if value
14
+ instance_variable_set "@#{name}", value
15
+ }
16
+ end
17
+
18
+ # Add a xmlsubel_mult type attribute (wrapper around attr_accessor)
19
+ def self.xmlsubel_mult(name) #:doc:
20
+ name = name.to_sym
21
+ self._xmlsubel(name)
22
+ self.xmlsubelmultiples << name
23
+ define_method(name){
24
+ if not self.instance_variables.index("@#{name}".to_sym)
25
+ instance_variable_set "@#{name}", XMLSubElements.new(self)
26
+ end
27
+ instance_variable_get "@#{name}"
28
+ }
29
+ end
30
+
31
+ # Add a name as being a subelement (mult or single)
32
+ def self._xmlsubel(name)
33
+ self.xmlsubels << name
34
+ end
35
+
36
+ # Class level variable to hold the list of subelements
37
+ def self.xmlsubels
38
+ @xmlsubels ||=[]
39
+ end
40
+
41
+ # Class level variable to hold the list of subelements that are multiple
42
+ def self.xmlsubelmultiples
43
+ @xmlsubelmultiples ||=[]
44
+ end
45
+
46
+ # Iterates over the object's XML subelements
47
+ def self.each_subel
48
+ if not self.instance_variables.index("@__subel_names".to_sym)
49
+ names = []
50
+ # Iterate all the superclasses that are still children of XMLElement
51
+ # and iterate each of the subelements
52
+ c = self
53
+ while c.ancestors.index(XMLCodec::XMLElement)
54
+ names += c.xmlsubels
55
+ c = c.superclass
56
+ end
57
+ @__subel_names = names
58
+ end
59
+ @__subel_names.each {|name| yield name}
60
+ end
61
+
62
+ # Iterate all the superclasses that are still children of XMLElement
63
+ # and check if any of them have the subelement mult defined
64
+ def self.subel_mult?(element)
65
+ if not self.instance_variables.index("@__subel_mult_names".to_sym)
66
+ names = []
67
+ c = self
68
+ while c.ancestors.index(XMLCodec::XMLElement)
69
+ names += c.xmlsubelmultiples
70
+ c = c.superclass
71
+ end
72
+ @__subel_mult_names = names
73
+ end
74
+ return @__subel_mult_names.index(element)? true : false
75
+ end
76
+
77
+ # Iterate all the superclasses that are still children of XMLElement
78
+ # and check if any of them have any subelements handled by this class
79
+ def get_subel(elclass)
80
+ names = elclass.get_elnames
81
+ c = self.class
82
+ while c.ancestors.index(XMLCodec::XMLElement)
83
+ names.each do |name|
84
+ if c.xmlsubels.index(name.to_sym)
85
+ return names[0].to_sym
86
+ end
87
+ end
88
+ c = c.superclass
89
+ end
90
+ return nil
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,33 @@
1
+ module XMLCodec
2
+ class XMLElement
3
+ public
4
+ # Method that checks if a given class has subelements. This is usually only
5
+ # used when exporting stuff.
6
+ def self.has_subelements?; false end
7
+ def has_subelements?; self.class.has_subelements? end
8
+
9
+ private
10
+ # Declare the class as having many subelements. Instances will have a
11
+ # method called #subelements that will return an instance of XMLSubElements
12
+ def self.xmlsubelements #:doc:
13
+ define_method(:subelements) {
14
+ @subelements ||= XMLSubElements.new(self)
15
+ }
16
+ define_method('<<') {|value|
17
+ subelements << value
18
+ }
19
+ define_method(:find_first_named) {|name|
20
+ subelements.find_first_named(name)
21
+ }
22
+ define_method('[]') {|name|
23
+ subelements.find_first_named(name)
24
+ }
25
+ define_method(:find_all_named) {|name|
26
+ subelements.find_all_named(name)
27
+ }
28
+ self.class_eval do
29
+ def self.has_subelements?; true; end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,41 @@
1
+ module XMLCodec
2
+ class XMLElement
3
+ public
4
+ # tests if the element is a value element as defined by 'elwithvalue'
5
+ def self.hasvalue?; false end
6
+ def hasvalue?; self.class.hasvalue? end
7
+
8
+ # tests if the element is a value element as defined by 'elallvalue'
9
+ def self.allvalue?; false end
10
+ def allvalue?; self.class.allvalue?; end
11
+
12
+ private
13
+ # Set the element as having a value. The element will have an initializer
14
+ # that takes a value as argument and an accessor named #value. This should
15
+ # be used for elements that contain only text and no subelements
16
+ def self.elwithvalue
17
+ self.class_eval do
18
+ def self.hasvalue?; true; end
19
+ end
20
+ self.class_eval do
21
+ def initialize(value=nil)
22
+ @value = value
23
+ end
24
+ end
25
+ attr_accessor :value
26
+ end
27
+
28
+ # Set the element as having a value that eats up any subelements as if they
29
+ # were text. The element will behave similarly to "elwithvalue" with an
30
+ # initializar that takes a value as argument and an accessor named #value
31
+ # and will consume all its subelements as if they were text. This should
32
+ # be used for elements that contain subelements that you want to treat as
33
+ # text like <content> in Atom
34
+ def self.elallvalue
35
+ self.elwithvalue
36
+ self.class_eval do
37
+ def self.allvalue?; true; end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -1,11 +1,19 @@
1
1
  require 'nokogiri'
2
2
 
3
3
  module XMLCodec
4
- VERSION = '0.3.1'
4
+ VERSION = '0.3.2'
5
5
  end
6
6
 
7
- require File.dirname(__FILE__) + '/XMLUtils'
8
- require File.dirname(__FILE__) + '/element'
9
- require File.dirname(__FILE__) + '/subelements'
10
- require File.dirname(__FILE__) + '/stream_object_parser'
11
- require File.dirname(__FILE__) + '/stream_parser'
7
+ require File.join(File.dirname(__FILE__),'XMLUtils')
8
+ require File.join(File.dirname(__FILE__),'element')
9
+ require File.join(File.dirname(__FILE__),'element_creation')
10
+ require File.join(File.dirname(__FILE__),'element_partial_export')
11
+ require File.join(File.dirname(__FILE__),'element_import')
12
+ require File.join(File.dirname(__FILE__),'element_export')
13
+ require File.join(File.dirname(__FILE__),'element_attrs')
14
+ require File.join(File.dirname(__FILE__),'element_value')
15
+ require File.join(File.dirname(__FILE__),'element_subel')
16
+ require File.join(File.dirname(__FILE__),'element_subelements')
17
+ require File.join(File.dirname(__FILE__),'subelements')
18
+ require File.join(File.dirname(__FILE__),'stream_object_parser')
19
+ require File.join(File.dirname(__FILE__),'stream_parser')
@@ -6,8 +6,8 @@ Gem::Specification.new do |s|
6
6
  s.platform = Gem::Platform::RUBY
7
7
 
8
8
  s.name = 'xmlcodec'
9
- s.version = '0.3.1'
10
- s.date = '2013-08-30'
9
+ s.version = '0.3.2'
10
+ s.date = '2013-09-04'
11
11
 
12
12
  s.summary = "Generic Importer/Exporter of XML formats"
13
13
  s.description = <<EOF
@@ -17,6 +17,7 @@ EOF
17
17
  s.authors = ["Pedro Côrte-Real"]
18
18
  s.email = 'pedro@pedrocr.net'
19
19
  s.homepage = 'https://github.com/pedrocr/xmlcodec'
20
+ s.license = 'LGPL-2.1'
20
21
 
21
22
  s.require_paths = %w[lib]
22
23
 
@@ -35,6 +36,14 @@ EOF
35
36
  Rakefile
36
37
  lib/XMLUtils.rb
37
38
  lib/element.rb
39
+ lib/element_attrs.rb
40
+ lib/element_creation.rb
41
+ lib/element_export.rb
42
+ lib/element_import.rb
43
+ lib/element_partial_export.rb
44
+ lib/element_subel.rb
45
+ lib/element_subelements.rb
46
+ lib/element_value.rb
38
47
  lib/stream_object_parser.rb
39
48
  lib/stream_parser.rb
40
49
  lib/subelements.rb
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xmlcodec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-08-30 00:00:00.000000000 Z
12
+ date: 2013-09-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri
16
- requirement: &84598170 !ruby/object:Gem::Requirement
16
+ requirement: &71026940 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *84598170
24
+ version_requirements: *71026940
25
25
  description: ! 'A framework to write object to XML mappers in Ruby that can then function
26
26
  both in whole-document manipulation as well as constant memory unlimited size importing
27
27
  and exporting of XML.
@@ -39,6 +39,14 @@ files:
39
39
  - Rakefile
40
40
  - lib/XMLUtils.rb
41
41
  - lib/element.rb
42
+ - lib/element_attrs.rb
43
+ - lib/element_creation.rb
44
+ - lib/element_export.rb
45
+ - lib/element_import.rb
46
+ - lib/element_partial_export.rb
47
+ - lib/element_subel.rb
48
+ - lib/element_subelements.rb
49
+ - lib/element_value.rb
42
50
  - lib/stream_object_parser.rb
43
51
  - lib/stream_parser.rb
44
52
  - lib/subelements.rb
@@ -57,7 +65,8 @@ files:
57
65
  - test/utils_test.rb
58
66
  - xmlcodec.gemspec
59
67
  homepage: https://github.com/pedrocr/xmlcodec
60
- licenses: []
68
+ licenses:
69
+ - LGPL-2.1
61
70
  post_install_message:
62
71
  rdoc_options:
63
72
  - -S