xommelier 0.1.19 → 0.1.20

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/Rakefile +2 -2
  2. data/examples/atom.rb +3 -3
  3. data/lib/xommelier.rb +9 -0
  4. data/lib/xommelier/atom/links_extension.rb +12 -2
  5. data/lib/xommelier/atom/source.rb +12 -2
  6. data/lib/xommelier/core_ext/boolean.rb +1 -0
  7. data/lib/xommelier/core_ext/float.rb +1 -1
  8. data/lib/xommelier/core_ext/numeric.rb +1 -1
  9. data/lib/xommelier/core_ext/time.rb +9 -1
  10. data/lib/xommelier/core_ext/uri.rb +6 -2
  11. data/lib/xommelier/open_search.rb +55 -40
  12. data/lib/xommelier/rss.rb +51 -6
  13. data/lib/xommelier/rss/atomic.rb +21 -0
  14. data/lib/xommelier/schemas/dublincore/dc.xsd +118 -0
  15. data/lib/xommelier/schemas/dublincore/dcmitype.xsd +52 -0
  16. data/lib/xommelier/schemas/dublincore/dcterms.xsd +382 -0
  17. data/lib/xommelier/schemas/dublincore/qualifieddc.xsd +40 -0
  18. data/lib/xommelier/schemas/dublincore/simpledc.xsd +39 -0
  19. data/lib/xommelier/schemas/opensearch.xsd +484 -0
  20. data/lib/xommelier/schemas/syndication/creativeCommons.xsd +17 -0
  21. data/lib/xommelier/schemas/syndication/fh.xsd +19 -0
  22. data/lib/xommelier/schemas/syndication/schematron.xsd +254 -0
  23. data/lib/xommelier/schemas/syndication/thr.xsd +39 -0
  24. data/lib/xommelier/schemas/syndication/trackback.xsd +18 -0
  25. data/lib/xommelier/version.rb +1 -1
  26. data/lib/xommelier/xml/element.rb +1 -0
  27. data/lib/xommelier/xml/element/serialization.rb +12 -11
  28. data/lib/xommelier/xml/element/structure.rb +19 -19
  29. data/lib/xommelier/xml/element/structure/property.rb +4 -0
  30. data/spec/fixtures/opensearch.full.xml +23 -0
  31. data/spec/functional/xommelier/atom/feed/building_hash_spec.rb +37 -0
  32. data/spec/functional/xommelier/atom/feed/building_spec.rb +33 -0
  33. data/spec/functional/{atom_feed_parsing_spec.rb → xommelier/atom/feed/parsing_spec.rb} +3 -4
  34. data/spec/functional/{atom_feed_thread_building_spec.rb → xommelier/atom/threading/building_spec.rb} +0 -0
  35. data/spec/functional/xommelier/open_search/description/building_spec.rb +36 -0
  36. data/spec/functional/xommelier/open_search/description/parsing_spec.rb +47 -0
  37. data/spec/functional/{rss_feed_building_spec.rb → xommelier/rss/rss/building_spec.rb} +0 -0
  38. data/spec/functional/{rss_feed_parsing_spec.rb → xommelier/rss/rss/parsing_spec.rb} +0 -0
  39. data/spec/lib/xommelier/rss/email_address_spec.rb +22 -0
  40. data/spec/lib/xommelier/xml/element_spec.rb +2 -2
  41. data/spec/spec_helper.rb +1 -0
  42. data/xommelier.gemspec +8 -8
  43. metadata +34 -14
  44. data/spec/functional/atom_feed_building_spec.rb +0 -31
  45. data/spec/functional/build_nested_document_from_hash_spec.rb +0 -39
@@ -0,0 +1,17 @@
1
+ <xs:schema
2
+ targetNamespace="http://backend.userland.com/creativeCommonsRssModule"
3
+ xmlns:xs="http://www.w3.org/2001/XMLSchema">
4
+ <xs:element name="license" type="xs:anyURI">
5
+ <xs:annotation>
6
+ <xs:documentation>
7
+ <![CDATA[One element is defined.
8
+
9
+ license -- if present as a sub-element of <channel>, indicates that the content of the RSS file is available under a license, indicated by a URL, which is the value of the license element. A list of some licenses that may be used in this context is on the Creative Commons website on this page, however the <license> element may point to licenses not authored by Creative Commons.
10
+
11
+ You may also use the <license> element as a sub-element of <item>. When used this way it applies only to the content of that item. If an item has a license, and the channel does too, the license on the item applies, i.e. the inner license overrides the outer one.
12
+
13
+ Multiple <license> elements are allowed, in either context, indicating that the content is available under multiple licenses.]]>
14
+ </xs:documentation>
15
+ </xs:annotation>
16
+ </xs:element>
17
+ </xs:schema>
@@ -0,0 +1,19 @@
1
+ <xs:schema version="1.0"
2
+ targetNamespace="http://purl.org/syndication/history/1.0"
3
+ xmlns="http://purl.org/syndication/history/1.0"
4
+ xmlns:xs="http://www.w3.org/2001/XMLSchema">
5
+ <xs:element name="complete">
6
+ <xs:annotation>
7
+ <xs:documentation>
8
+ <![CDATA[This implements an fh:complete tag as specified in http://tools.ietf.org/html/rfc5005#section-2]]>
9
+ </xs:documentation>
10
+ </xs:annotation>
11
+ </xs:element>
12
+ <xs:element name="archive">
13
+ <xs:annotation>
14
+ <xs:documentation>
15
+ <![CDATA[This implements an fh:archive tag as specified in http://tools.ietf.org/html/rfc5005#section-4]]>
16
+ </xs:documentation>
17
+ </xs:annotation>
18
+ </xs:element>
19
+ </xs:schema>
@@ -0,0 +1,254 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!-- schemaVersion of 2001/02/15 -->
3
+ <xs:schema targetNamespace="http://www.ascc.net/xml/schematron" xmlns:sch="http://www.ascc.net/xml/schematron" xmlns="http://www.ascc.net/xml/schematron" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="+//IDN sinica.edu.tw//SGML W3C XML Schema for Schematron 1.5//EN">
4
+ <xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/xml.xsd">
5
+ <xs:annotation>
6
+ <xs:documentation>
7
+ Get access to the xml: attribute groups for xml:lang
8
+ </xs:documentation>
9
+ </xs:annotation>
10
+ </xs:import>
11
+ <xs:annotation>
12
+ <xs:documentation source="http://www.ascc.net/xml/resource/schematron/schematron.html" xml:lang="en"/>
13
+ </xs:annotation>
14
+ <xs:element name="active">
15
+ <xs:complexType mixed="true">
16
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
17
+ <xs:element ref="sch:dir"/>
18
+ <xs:element ref="sch:emph"/>
19
+ <xs:element ref="sch:span"/>
20
+ </xs:choice>
21
+ <xs:attribute name="pattern" type="xs:IDREF" use="required"/>
22
+ </xs:complexType>
23
+ </xs:element>
24
+ <xs:element name="assert">
25
+ <xs:complexType mixed="true">
26
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
27
+ <xs:element ref="sch:name"/>
28
+ <xs:element ref="sch:emph"/>
29
+ <xs:element ref="sch:dir"/>
30
+ <xs:element ref="sch:span"/>
31
+ <xs:any namespace="##other" processContents="lax"/>
32
+ </xs:choice>
33
+ <xs:attribute name="test" type="xs:string" use="required"/>
34
+ <xs:attribute name="role" type="xs:NMTOKEN"/>
35
+ <xs:attribute name="id" type="xs:string"/>
36
+ <xs:attribute name="diagnostics" type="xs:IDREFS"/>
37
+ <xs:attribute name="icon" type="xs:anyURI"/>
38
+ <xs:attribute name="subject" type="xs:string" default="."/>
39
+ <xs:attribute ref="xml:lang"/>
40
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
41
+ </xs:complexType>
42
+ </xs:element>
43
+ <xs:element name="diagnostic">
44
+ <xs:complexType mixed="true">
45
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
46
+ <xs:element ref="sch:value-of"/>
47
+ <xs:element ref="sch:emph"/>
48
+ <xs:element ref="sch:dir"/>
49
+ <xs:element ref="sch:span"/>
50
+ <xs:any namespace="##other" processContents="lax"/>
51
+ </xs:choice>
52
+ <xs:attribute name="id" type="xs:ID" use="required"/>
53
+ <xs:attribute name="icon" type="xs:anyURI"/>
54
+ <xs:attribute ref="xml:lang"/>
55
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
56
+ </xs:complexType>
57
+ </xs:element>
58
+ <xs:element name="diagnostics">
59
+ <xs:complexType>
60
+ <xs:sequence>
61
+ <xs:element ref="diagnostic" minOccurs="0" maxOccurs="unbounded"/>
62
+ </xs:sequence>
63
+ </xs:complexType>
64
+ </xs:element>
65
+ <xs:element name="dir">
66
+ <xs:complexType>
67
+ <xs:simpleContent>
68
+ <xs:extension base="xs:string">
69
+ <xs:attribute name="value">
70
+ <xs:simpleType>
71
+ <xs:restriction base="xs:NMTOKEN">
72
+ <xs:enumeration value="ltr"/>
73
+ <xs:enumeration value="rtl"/>
74
+ </xs:restriction>
75
+ </xs:simpleType>
76
+ </xs:attribute>
77
+ </xs:extension>
78
+ </xs:simpleContent>
79
+ </xs:complexType>
80
+ </xs:element>
81
+ <xs:element name="emph" type="xs:string"/>
82
+ <xs:element name="extends">
83
+ <xs:complexType>
84
+ <xs:attribute name="rule" type="xs:string" use="required"/>
85
+ </xs:complexType>
86
+ </xs:element>
87
+ <xs:element name="key">
88
+ <xs:complexType>
89
+ <xs:attribute name="name" type="xs:NMTOKEN" use="required"/>
90
+ <xs:attribute name="path" type="xs:string" use="required"/>
91
+ <xs:attribute name="icon" type="xs:anyURI"/>
92
+ </xs:complexType>
93
+ </xs:element>
94
+ <xs:element name="name">
95
+ <xs:complexType>
96
+ <xs:attribute name="path" type="xs:string" default="."/>
97
+ </xs:complexType>
98
+ </xs:element>
99
+ <xs:element name="ns">
100
+ <xs:complexType>
101
+ <xs:attribute name="uri" type="xs:anyURI" use="required"/>
102
+ <xs:attribute name="prefix" type="xs:NCName"/>
103
+ </xs:complexType>
104
+ </xs:element>
105
+ <xs:element name="p">
106
+ <xs:complexType mixed="true">
107
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
108
+ <xs:element ref="sch:dir"/>
109
+ <xs:element ref="sch:emph"/>
110
+ <xs:element ref="sch:span"/>
111
+ </xs:choice>
112
+ <xs:attribute name="id" type="xs:string"/>
113
+ <xs:attribute name="class" type="xs:string"/>
114
+ <xs:attribute name="icon" type="xs:anyURI"/>
115
+ <xs:attribute ref="xml:lang"/>
116
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
117
+ </xs:complexType>
118
+ </xs:element>
119
+ <xs:element name="pattern">
120
+ <xs:complexType>
121
+ <xs:sequence>
122
+ <xs:element ref="p" minOccurs="0" maxOccurs="unbounded"/>
123
+ <xs:element ref="sch:rule" maxOccurs="unbounded"/>
124
+ </xs:sequence>
125
+ <xs:attribute name="name" type="xs:string" use="required"/>
126
+ <xs:attribute name="see" type="xs:anyURI"/>
127
+ <xs:attribute name="id" type="xs:string"/>
128
+ <xs:attribute name="icon" type="xs:anyURI"/>
129
+ </xs:complexType>
130
+ </xs:element>
131
+ <xs:element name="phase">
132
+ <xs:complexType>
133
+ <xs:sequence>
134
+ <xs:element ref="sch:p" minOccurs="0" maxOccurs="unbounded"/>
135
+ <xs:element ref="sch:active" maxOccurs="unbounded"/>
136
+ </xs:sequence>
137
+ <xs:attribute name="id" type="xs:string" use="required"/>
138
+ <xs:attribute name="fpi" type="xs:string"/>
139
+ <xs:attribute name="icon" type="xs:anyURI"/>
140
+ </xs:complexType>
141
+ </xs:element>
142
+ <xs:element name="report">
143
+ <xs:complexType mixed="true">
144
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
145
+ <xs:element ref="sch:name"/>
146
+ <xs:element ref="sch:emph"/>
147
+ <xs:element ref="sch:dir"/>
148
+ <xs:element ref="sch:span"/>
149
+ <xs:any namespace="##other" processContents="lax"/>
150
+ </xs:choice>
151
+ <xs:attribute name="test" type="xs:string" use="required"/>
152
+ <xs:attribute name="role" type="xs:NMTOKEN"/>
153
+ <xs:attribute name="id" type="xs:string"/>
154
+ <xs:attribute name="diagnostics" type="xs:IDREFS"/>
155
+ <xs:attribute name="icon" type="xs:anyURI"/>
156
+ <xs:attribute name="subject" type="xs:string" default="."/>
157
+ <xs:attribute ref="xml:lang"/>
158
+ </xs:complexType>
159
+ </xs:element>
160
+ <xs:element name="rule">
161
+ <xs:complexType>
162
+ <xs:choice maxOccurs="unbounded">
163
+ <xs:element ref="sch:assert"/>
164
+ <xs:element ref="sch:report"/>
165
+ <xs:element ref="sch:key"/>
166
+ <xs:element ref="sch:extends"/>
167
+ </xs:choice>
168
+ <xs:attribute name="context" type="xs:string"/>
169
+ <xs:attribute name="abstract" type="xs:boolean" default="false"/>
170
+ <xs:attribute name="role" type="xs:NMTOKEN"/>
171
+ <xs:attribute name="id" type="xs:string"/>
172
+ </xs:complexType>
173
+ </xs:element>
174
+ <xs:element name="schema">
175
+ <xs:complexType>
176
+ <xs:sequence>
177
+ <xs:element ref="sch:title" minOccurs="0"/>
178
+ <xs:element ref="sch:ns" minOccurs="0" maxOccurs="unbounded"/>
179
+ <xs:element ref="sch:p" minOccurs="0" maxOccurs="unbounded"/>
180
+ <xs:element ref="sch:phase" minOccurs="0" maxOccurs="unbounded"/>
181
+ <xs:element ref="sch:pattern" maxOccurs="unbounded"/>
182
+ <xs:element ref="sch:p" minOccurs="0" maxOccurs="unbounded"/>
183
+ <xs:element ref="sch:diagnostics" minOccurs="0"/>
184
+ </xs:sequence>
185
+ <xs:attribute name="id" type="xs:ID"/>
186
+ <xs:attribute name="fpi" type="xs:string"/>
187
+ <xs:attribute name="schemaVersion" type="xs:string"/>
188
+ <xs:attribute name="defaultPhase" type="xs:string"/>
189
+ <xs:attribute name="icon" type="xs:anyURI"/>
190
+ <xs:attribute name="ns" type="xs:anyURI"/>
191
+ <xs:attribute name="version" type="xs:string" default="1.5"/>
192
+ <xs:attribute ref="xml:lang"/>
193
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
194
+ </xs:complexType>
195
+ <xs:unique name="assertId">
196
+ <xs:selector xpath="sch:pattern/sch:rule/sch:assert"/>
197
+ <xs:field xpath="@id"/>
198
+ </xs:unique>
199
+ <xs:unique name="reportId">
200
+ <xs:selector xpath="sch:pattern/sch:rule/sch:report"/>
201
+ <xs:field xpath="@id"/>
202
+ </xs:unique>
203
+ <xs:unique name="ruleId">
204
+ <xs:selector xpath="sch:pattern/sch:rule"/>
205
+ <xs:field xpath="@id"/>
206
+ </xs:unique>
207
+ <xs:unique name="patternId">
208
+ <xs:selector xpath="sch:pattern"/>
209
+ <xs:field xpath="@id"/>
210
+ </xs:unique>
211
+ <xs:unique name="pId">
212
+ <xs:selector xpath=".//sch:p"/>
213
+ <xs:field xpath="@id"/>
214
+ </xs:unique>
215
+ <xs:key name="phaseId">
216
+ <xs:selector xpath="sch:phase"/>
217
+ <xs:field xpath="@id"/>
218
+ </xs:key>
219
+ <xs:keyref name="activePattern" refer="patternId">
220
+ <xs:selector xpath="sch:phase/sch:active"/>
221
+ <xs:field xpath="@pattern"/>
222
+ </xs:keyref>
223
+ <xs:keyref name="extendsRule" refer="ruleId">
224
+ <xs:selector xpath="sch:pattern/sch:rule/sch:extends"/>
225
+ <xs:field xpath="@rule"/>
226
+ </xs:keyref>
227
+ <xs:keyref name="defaultPhase" refer="phaseId">
228
+ <xs:selector xpath="."/>
229
+ <xs:field xpath="@defaultPhase"/>
230
+ </xs:keyref>
231
+ <!-- Define the identity constraints -->
232
+ </xs:element>
233
+ <xs:element name="span">
234
+ <xs:complexType>
235
+ <xs:simpleContent>
236
+ <xs:extension base="xs:string">
237
+ <xs:attribute name="class" type="xs:string"/>
238
+ </xs:extension>
239
+ </xs:simpleContent>
240
+ </xs:complexType>
241
+ </xs:element>
242
+ <xs:element name="title">
243
+ <xs:complexType mixed="true">
244
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
245
+ <xs:element ref="sch:dir"/>
246
+ </xs:choice>
247
+ </xs:complexType>
248
+ </xs:element>
249
+ <xs:element name="value-of">
250
+ <xs:complexType>
251
+ <xs:attribute name="select" type="xs:string" use="required"/>
252
+ </xs:complexType>
253
+ </xs:element>
254
+ </xs:schema>
@@ -0,0 +1,39 @@
1
+ <xs:schema version="1.0"
2
+ targetNamespace="http://purl.org/syndication/thread/1.0"
3
+ xmlns="http://purl.org/syndication/thread/1.0"
4
+ xmlns:xs="http://www.w3.org/2001/XMLSchema">
5
+ <xs:element name="in-reply-to">
6
+ <xs:annotation>
7
+ <xs:documentation>
8
+ <![CDATA[http://tools.ietf.org/html/rfc4685#section-3]]>
9
+ </xs:documentation>
10
+ </xs:annotation>
11
+ <xs:complexType>
12
+ <xs:attribute name="ref" type="xs:string" />
13
+ <xs:attribute name="href" type="xs:anyURI" />
14
+ <xs:attribute name="type" type="xs:string" />
15
+ <xs:attribute name="source" type="xs:anyURI" />
16
+ </xs:complexType>
17
+ </xs:element>
18
+ <xs:element name="total" type="xs:nonNegativeInteger">
19
+ <xs:annotation>
20
+ <xs:documentation>
21
+ <![CDATA[http://tools.ietf.org/html/rfc4685#section-5]]>
22
+ </xs:documentation>
23
+ </xs:annotation>
24
+ </xs:element>
25
+ <xs:attribute name="count" type="xs:nonNegativeInteger">
26
+ <xs:annotation>
27
+ <xs:documentation>
28
+ <![CDATA[<link rel="replies" thr:count="3"> described in http://tools.ietf.org/html/rfc4685#section-4]]>
29
+ </xs:documentation>
30
+ </xs:annotation>
31
+ </xs:attribute>
32
+ <xs:attribute name="updated" type="xs:dateTime">
33
+ <xs:annotation>
34
+ <xs:documentation>
35
+ <![CDATA[<link rel="replies" thr:updated="3"> described in http://tools.ietf.org/html/rfc4685#section-4]]>
36
+ </xs:documentation>
37
+ </xs:annotation>
38
+ </xs:attribute>
39
+ </xs:schema>
@@ -0,0 +1,18 @@
1
+ <xs:schema
2
+ targetNamespace="http://madskills.com/public/xml/rss/module/trackback/"
3
+ xmlns:xs="http://www.w3.org/2001/XMLSchema">
4
+ <xs:element name="ping" type="xs:anyURI">
5
+ <xs:annotation>
6
+ <xs:documentation>
7
+ <![CDATA[The trackback:ping is this feed item's TrackBack url.]]>
8
+ </xs:documentation>
9
+ </xs:annotation>
10
+ </xs:element>
11
+ <xs:element name="about" type="xs:anyURI">
12
+ <xs:annotation>
13
+ <xs:documentation>
14
+ <![CDATA[The trackback:about is the original item that was pinged, letting the original author know that the information was syndicated using a TrackBack.]]>
15
+ </xs:documentation>
16
+ </xs:annotation>
17
+ </xs:element>
18
+ </xs:schema>
@@ -1,3 +1,3 @@
1
1
  module Xommelier
2
- VERSION = '0.1.19'
2
+ VERSION = '0.1.20'
3
3
  end
@@ -34,6 +34,7 @@ module Xommelier
34
34
  end
35
35
 
36
36
  def options=(options = {})
37
+ super
37
38
  @options = options
38
39
  unless @options[:validate]
39
40
  @options[:validate] = !!xmlns.try(:schema)
@@ -116,19 +116,20 @@ module Xommelier
116
116
  def to_hash
117
117
  attributes.dup.tap do |hash|
118
118
  @elements.each do |name, value|
119
- options = element_options(name)
120
- type = options.type
121
- value = Array.wrap(value)
122
- if type < Xml::Element
123
- value = value.map(&:to_hash)
124
- end
125
- if value.count > 1
126
- name = name.to_s.pluralize.to_sym
119
+ element = element_options(name)
120
+ if element.multiple?
121
+ if value.count > 1
122
+ name = element.plural
123
+ value = value.map { |v| v.to_hash } if element.complex_type?
124
+ else
125
+ value = value.first.to_hash
126
+ end
127
127
  else
128
- value = value.first
128
+ value = value.to_hash if element.complex_type?
129
129
  end
130
130
  hash[name] = value
131
131
  end
132
+ hash[:text] = text if text?
132
133
  end
133
134
  end
134
135
 
@@ -177,7 +178,7 @@ module Xommelier
177
178
  element = self.class.elements[name]
178
179
  result << element.ns
179
180
  result += attributes.keys.map { |attr_name| attribute_options(attr_name).ns }
180
- if element.type < Xml::Element
181
+ if element.complex_type?
181
182
  Array(children).each do |child|
182
183
  result += child.children_namespaces
183
184
  end
@@ -224,7 +225,7 @@ module Xommelier
224
225
  # @param [Nokogiri::XML::Node] node
225
226
  # @param [Xommelier::Xml::Element::Structure::Element] options
226
227
  def typecast_element(node, options)
227
- if options.type < Xml::Element
228
+ if options.complex_type?
228
229
  options.type.from_xommelier(xml_document, node: node)
229
230
  else
230
231
  options.type.from_xommelier(node.text)
@@ -84,8 +84,9 @@ module Xommelier
84
84
  else
85
85
  xmlns
86
86
  end
87
- elements[name] = Element.new(name, options)
88
- define_element_accessors(name)
87
+ element = Element.new(name, options)
88
+ elements[name] = element
89
+ define_element_accessors(element)
89
90
  end
90
91
 
91
92
  # Defines containing attribute
@@ -96,7 +97,7 @@ module Xommelier
96
97
  end
97
98
 
98
99
  # Defines containing text
99
- def text(options = {})
100
+ def text(*)
100
101
  define_text_accessors
101
102
  end
102
103
 
@@ -114,8 +115,8 @@ module Xommelier
114
115
 
115
116
  private
116
117
 
117
- def define_element_accessors(name)
118
- element = elements[name]
118
+ def define_element_accessors(element)
119
+ name = element.name
119
120
  if element.multiple?
120
121
  # Define plural accessors
121
122
  plural = element.plural
@@ -123,7 +124,7 @@ module Xommelier
123
124
  rw_accessor(plural) do |*args|
124
125
  args.flatten.each_with_index do |object, index|
125
126
  write_element(name, object, index)
126
- end if args.any?
127
+ end if args.length > 0
127
128
 
128
129
  @elements[name] ||= []
129
130
  end
@@ -131,15 +132,14 @@ module Xommelier
131
132
  # Define singular accessors for first element
132
133
  unless element.numbers_equal?
133
134
  rw_accessor(name) do |*args|
134
- send(plural, [args[0]]) if args[0]
135
+ send(plural, [args[0]]) if args.length == 1
135
136
  send(plural)[0]
136
137
  end
137
138
  end
138
139
  else
139
140
  # Define singular accessors
140
- name = name.to_sym
141
141
  rw_accessor(name) do |*args|
142
- write_element(name, args[0]) if args[0]
142
+ write_element(name, args[0]) if args.length == 1
143
143
  read_element(name)
144
144
  end
145
145
  end
@@ -147,14 +147,14 @@ module Xommelier
147
147
 
148
148
  def define_attribute_accessors(name)
149
149
  rw_accessor(name) do |*args|
150
- write_attribute(name.to_s, args[0]) if args[0]
150
+ write_attribute(name, args[0]) if args.length == 1
151
151
  read_attribute(name)
152
152
  end
153
153
  end
154
154
 
155
155
  def define_text_accessors
156
156
  rw_accessor(:text) do |*args|
157
- write_text(args[0]) if args[0]
157
+ write_text(args[0]) if args.length == 1
158
158
  read_text
159
159
  end
160
160
  alias_attribute :content, :text
@@ -178,10 +178,9 @@ module Xommelier
178
178
  end
179
179
 
180
180
  def options=(options = {})
181
- if @options.key?(:element_name)
182
- element_name(@options.delete(:element_name))
181
+ if options.key?(:element_name)
182
+ element_name(options.delete(:element_name))
183
183
  end
184
- super(options)
185
184
  end
186
185
 
187
186
  def element_name(value = nil)
@@ -199,19 +198,20 @@ module Xommelier
199
198
  end
200
199
 
201
200
  def write_element(name, value, index = nil)
202
- type = element_options(name).type
201
+ element = element_options(name)
202
+ type = element.type
203
203
  unless value.is_a?(type)
204
- value = if (type < Xommelier::Xml::Element) && !value.is_a?(Nokogiri::XML::Node)
204
+ value = if element.complex_type? && !value.is_a?(Nokogiri::XML::Node)
205
205
  type.new(value)
206
206
  else
207
207
  type.from_xommelier(value)
208
208
  end
209
209
  end
210
210
  if index
211
- @elements[name.to_sym] ||= []
212
- @elements[name.to_sym][index] = value
211
+ @elements[element.name] ||= []
212
+ @elements[element.name][index] = value
213
213
  else
214
- @elements[name.to_sym] = value
214
+ @elements[element.name] = value
215
215
  end
216
216
  end
217
217