xmlcodec 0.3.1 → 0.3.2

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