Class: Saxaphone::Element
- Inherits:
-
Object
- Object
- Saxaphone::Element
- Defined in:
- lib/saxaphone/element.rb
Defined Under Namespace
Classes: ElementHandler
Constant Summary collapse
- @@base_class_name =
'Saxaphone::Element'
Instance Attribute Summary collapse
-
#attributes ⇒ Object
Returns the value of attribute attributes.
-
#content ⇒ Object
Returns the value of attribute content.
-
#name ⇒ Object
Returns the value of attribute name.
Class Method Summary collapse
-
.element_attribute(element_name, options = {}) ⇒ Object
Define a single element that should be stored as an attribute.
-
.element_attributes(element_names) ⇒ Object
Define elements that should be stored as attributes:.
- .handler_for(element_name) ⇒ Object
-
.has_element(element_name, class_name = @@base_class_name, &block) ⇒ Object
Define what to do for a particular child element.
- .parse(xml) ⇒ Object
-
.setup(&block) ⇒ Object
A block can be passed to
setup
, which is called after the element is initialized. -
.store_attributes(*attribute_names) ⇒ Object
Define a white list of the attributes that are extracted from the XML element and stored in the attribute hash:.
- .stored_attributes ⇒ Object
Instance Method Summary collapse
- #add_element(element) ⇒ Object
- #append_content(string) ⇒ Object
- #element_for(element_name) ⇒ Object
-
#initialize(name = '', content = '', attribute_array = []) ⇒ Element
constructor
A new instance of Element.
- #setup ⇒ Object
Constructor Details
#initialize(name = '', content = '', attribute_array = []) ⇒ Element
Returns a new instance of Element.
169 170 171 172 173 174 |
# File 'lib/saxaphone/element.rb', line 169 def initialize(name = '', content = '', attribute_array = []) self.name = name self.content = content self.attributes = Hash[attribute_array.select { |(key, value)| self.class.stored_attributes.include?(key) }] setup end |
Instance Attribute Details
#attributes ⇒ Object
Returns the value of attribute attributes.
168 169 170 |
# File 'lib/saxaphone/element.rb', line 168 def attributes @attributes end |
#content ⇒ Object
Returns the value of attribute content.
168 169 170 |
# File 'lib/saxaphone/element.rb', line 168 def content @content end |
#name ⇒ Object
Returns the value of attribute name.
168 169 170 |
# File 'lib/saxaphone/element.rb', line 168 def name @name end |
Class Method Details
.element_attribute(element_name, options = {}) ⇒ Object
Define a single element that should be stored as an attribute.
WidgetElement < Saxaphone::Element
element_attribute 'price'
end
element = WidgetElement.parse %{
<widget>
<price>4.33</price>
</widget>
}
element.attributes # => {"price" => "4.33"}
The name of the stored attribute can optionally be changed with the :as
option:
WidgetElement < Saxaphone::Element
element_attribute 'price', as: 'dollars'
end
element = WidgetElement.parse %{
<widget>
<price>4.33</price>
</widget>
}
element.attributes # => {"dollars" => "4.33"}
78 79 80 81 82 83 84 |
# File 'lib/saxaphone/element.rb', line 78 def element_attribute(element_name, = {}) converted_name = .delete(:as) has_element(element_name) do |element| attributes[converted_name || element.name] = element.content end end |
.element_attributes(element_names) ⇒ Object
Define elements that should be stored as attributes:
WidgetElement < Saxaphone::Element
element_attributes %w(color price)
end
element = WidgetElement.parse %{
<widget>
<color>red</color>
<price>4.33</price>
</widget>
}
element.attributes # => => “red”, “price” => “4.33”
44 45 46 47 48 |
# File 'lib/saxaphone/element.rb', line 44 def element_attributes(element_names) element_names.each do |element_name| element_attribute(element_name) end end |
.handler_for(element_name) ⇒ Object
150 151 152 |
# File 'lib/saxaphone/element.rb', line 150 def handler_for(element_name) element_handlers[element_name] || element_handlers['*'] end |
.has_element(element_name, class_name = @@base_class_name, &block) ⇒ Object
Define what to do for a particular child element. After the element is parsed, it is passed to the block:
WidgetElement < Saxaphone::Element
attr_accessor :cents
has_element 'price' do |element|
self.cents = element.content.to_f * 100
end
end
element = WidgetElement.parse %{
<widget>
<price>4.33</price>
</widget>
}
element.cents # => 433.0
It is possible to define the class name that is used to parse the child element:
PriceElement < Saxaphone::Element
def cents
content.to_f * 100
end
end
WidgetElement < Saxaphone::Element
attr_accessor :cents
has_element 'price', 'PriceElement' do |element|
self.cents = element.cents
end
end
The children elements can have children of their own,
and each uses has_element to define what to do.
125 126 127 |
# File 'lib/saxaphone/element.rb', line 125 def has_element(element_name, class_name = @@base_class_name, &block) element_handlers[element_name] = ElementHandler.new(class_name, block) end |
.parse(xml) ⇒ Object
158 159 160 |
# File 'lib/saxaphone/element.rb', line 158 def parse(xml) Saxaphone::Document.parse(xml, self) end |
.setup(&block) ⇒ Object
A block can be passed to setup
, which is called after the element is initialized.
WidgetElement < Saxaphone::Element
attr_accessor :foo
setup do
self.foo = 'bar'
end
end
It is recommended to use setup rather than
overriding initialize.
25 26 27 |
# File 'lib/saxaphone/element.rb', line 25 def setup(&block) define_method(:setup, &block) end |
.store_attributes(*attribute_names) ⇒ Object
Define a white list of the attributes that are extracted from the XML element and stored in the attribute hash:
WidgetElement < Saxaphone::Element
store_attributes 'name', 'color'
end
element = WidgetElement.parse %{
<widget name="Acme" color="red" price="3.21">
...
</widget>
}
element.attributes # => {"name" => "Acme", "color" => "red"}
Notice that the “price” attribute is not stored.
146 147 148 |
# File 'lib/saxaphone/element.rb', line 146 def store_attributes(*attribute_names) @stored_attributes = attribute_names.flatten.to_set end |
.stored_attributes ⇒ Object
154 155 156 |
# File 'lib/saxaphone/element.rb', line 154 def stored_attributes @stored_attributes ||= Set.new end |
Instance Method Details
#add_element(element) ⇒ Object
179 180 181 182 183 |
# File 'lib/saxaphone/element.rb', line 179 def add_element(element) if element_handler = self.class.handler_for(element.name) instance_exec(element, &element_handler.proc) if element_handler.proc end end |
#append_content(string) ⇒ Object
194 195 196 |
# File 'lib/saxaphone/element.rb', line 194 def append_content(string) content << string end |
#element_for(element_name) ⇒ Object
185 186 187 188 189 190 191 192 |
# File 'lib/saxaphone/element.rb', line 185 def element_for(element_name) if element_handler = self.class.handler_for(element_name) Saxaphone::Util.constantize(element_handler.class_name) else Saxaphone::Element end end |
#setup ⇒ Object
176 177 |
# File 'lib/saxaphone/element.rb', line 176 def setup end |