Class: XMLCodec::XMLElement
- Inherits:
-
Object
- Object
- XMLCodec::XMLElement
- Defined in:
- lib/element.rb,
lib/element_attrs.rb,
lib/element_subel.rb,
lib/element_value.rb,
lib/element_export.rb,
lib/element_import.rb,
lib/element_creation.rb,
lib/element_subelements.rb,
lib/element_partial_export.rb
Overview
This class should be inherited from to create classes that are able to import and export XML elements and their children. It provides three main functions: xmlattr, xmlsubel and xmlsubel_mult.
To create an importer/exporter for a XML format all that’s needed is to create a class for each of the elements and then declare their atributes and subelements.
Two other functions have an important role. elname declares the name of the XML element the class represents. elwithvalue declares that the element has no subelements and includes only text content.
After the class is defined import_xml can be used to import the content from a Nokogiri Element or Document and create_xml can be used to create the XML DOM of the element as a child to a Nokogiri Element or Document. For big documents these are usually too slow and memory hungry, using xml_text to export to XML and import_xml_text to import XML are probably better ideas. import_xml_text is just a utility function around XMLStreamObjectParser, that allow more flexible stream parsing of XML files while still using the same XMLElement objects.
Constant Summary collapse
- INDENT_STR =
' '
- CACHE =
{}
Instance Attribute Summary collapse
-
#__parent ⇒ Object
Returns the value of attribute __parent.
-
#__xml_text ⇒ Object
Returns the value of attribute __xml_text.
-
#element_id ⇒ Object
Returns the value of attribute element_id.
-
#parent_id ⇒ Object
Returns the value of attribute parent_id.
Class Method Summary collapse
-
.allvalue? ⇒ Boolean
tests if the element is a value element as defined by ‘elallvalue’.
-
.get_element_class(name) ⇒ Object
Gets the class for a certain element name.
-
.get_element_names(name) ⇒ Object
Gets the possible element names for a certain element.
-
.has_subelements? ⇒ Boolean
Method that checks if a given class has subelements.
-
.hasvalue? ⇒ Boolean
tests if the element is a value element as defined by ‘elwithvalue’.
-
.import_xml(obj) ⇒ Object
Import the XML into an object from a Nokogiri XML Node or Document or from a string.
-
.new_with_content(attrs, children) ⇒ Object
Create a new element passing it all the atributes, children and texts.
Instance Method Summary collapse
-
#add_attr(attrs) ⇒ Object
add the attributes passed as a hash to the element.
-
#add_subel(children) ⇒ Object
add the subelements into the element.
-
#add_subelements(all_children) ⇒ Object
If the class is one with many subelements import all of them into the object.
-
#add_texts(texts) ⇒ Object
add the text elements into the element.
- #allvalue? ⇒ Boolean
-
#create_close_tag ⇒ Object
returns a string with the closing tag for the element.
-
#create_open_tag ⇒ Object
returns a string with the opening tag for the element.
-
#create_xml(parent) ⇒ Object
Creates the xml for the element inside the parent element.
-
#create_xml_attr(parent) ⇒ Object
Creates the XML for the atributes.
-
#create_xml_subel(parent) ⇒ Object
Creates the XML subelements.
-
#create_xml_subelements(parent) ⇒ Object
Create the XML of the SubElements.
-
#delete_element(element) ⇒ Object
Remove the given subelement from the element.
-
#end_partial_export(file) ⇒ Object
Ends the partial exporting of the element.
- #has_subelements? ⇒ Boolean
- #hasvalue? ⇒ Boolean
-
#partial_export(file) ⇒ Object
Export this element into a file.
-
#start_partial_export(file) ⇒ Object
Starts to export the element to a file.
-
#xml_text ⇒ Object
create the XML text of the element.
Instance Attribute Details
#__parent ⇒ Object
Returns the value of attribute __parent.
33 34 35 |
# File 'lib/element.rb', line 33 def __parent @__parent end |
#__xml_text ⇒ Object
Returns the value of attribute __xml_text.
32 33 34 |
# File 'lib/element.rb', line 32 def __xml_text @__xml_text end |
#element_id ⇒ Object
Returns the value of attribute element_id.
32 33 34 |
# File 'lib/element.rb', line 32 def element_id @element_id end |
#parent_id ⇒ Object
Returns the value of attribute parent_id.
32 33 34 |
# File 'lib/element.rb', line 32 def parent_id @parent_id end |
Class Method Details
.allvalue? ⇒ Boolean
tests if the element is a value element as defined by ‘elallvalue’
9 |
# File 'lib/element_value.rb', line 9 def self.allvalue?; false end |
.get_element_class(name) ⇒ Object
Gets the class for a certain element name.
139 140 141 142 143 144 145 |
# File 'lib/element.rb', line 139 def self.get_element_class(name) cl = elclasses[name.to_sym] if not cl and class_variable_get(:@@strict_parsing) raise ElementClassNotFound, "No class defined for element type: '" + name.to_s + "'" end cl end |
.get_element_names(name) ⇒ Object
Gets the possible element names for a certain element.
148 149 150 |
# File 'lib/element.rb', line 148 def self.get_element_names(name) get_element_class(name).get_elnames end |
.has_subelements? ⇒ Boolean
Method that checks if a given class has subelements. This is usually only used when exporting stuff.
6 |
# File 'lib/element_subelements.rb', line 6 def self.has_subelements?; false end |
.hasvalue? ⇒ Boolean
tests if the element is a value element as defined by ‘elwithvalue’
5 |
# File 'lib/element_value.rb', line 5 def self.hasvalue?; false end |
.import_xml(obj) ⇒ Object
Import the XML into an object from a Nokogiri XML Node or Document or from a string.
6 7 8 9 10 11 12 13 14 15 |
# File 'lib/element_import.rb', line 6 def self.import_xml(obj) if obj.instance_of? String _import_xml_text(obj) elsif obj.instance_of? Nokogiri::XML::Node or obj.instance_of? Nokogiri::XML::Document _import_xml_dom(obj) else nil end end |
.new_with_content(attrs, children) ⇒ Object
Create a new element passing it all the atributes, children and texts
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/element_creation.rb', line 5 def self.new_with_content(attrs, children) text_children = [] element_children = [] children.each do |c| if c.is_a? String text_children << c else element_children << c end end obj = self.allocate obj.add_attr(attrs) obj.add_subel(element_children) obj.add_texts(text_children) if obj.has_subelements? obj.add_subelements(children) end obj end |
Instance Method Details
#add_attr(attrs) ⇒ Object
add the attributes passed as a hash to the element
28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/element_creation.rb', line 28 def add_attr(attrs) attrs.each do |name, value| if not self.class.attr_names.include?(name.to_sym) if self.class.class_variable_get(:@@strict_parsing) raise ElementAttributeNotFound, "No attribute '#{name}' defined for class '#{self.class}'" end else self.send("#{name}=", value) end end end |
#add_subel(children) ⇒ Object
add the subelements into the element
48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/element_creation.rb', line 48 def add_subel(children) children.each do |c| if subel_name = get_subel(c.class) if self.class.subel_mult? subel_name self.send(subel_name) << c else self.send(subel_name.to_s+'=', c) end end end end |
#add_subelements(all_children) ⇒ Object
If the class is one with many subelements import all of them into the object.
62 63 64 |
# File 'lib/element_creation.rb', line 62 def add_subelements(all_children) all_children.each {|c| self.subelements << c} end |
#add_texts(texts) ⇒ Object
add the text elements into the element
41 42 43 44 45 |
# File 'lib/element_creation.rb', line 41 def add_texts(texts) if self.hasvalue? @value = texts.join end end |
#allvalue? ⇒ Boolean
10 |
# File 'lib/element_value.rb', line 10 def allvalue?; self.class.allvalue?; end |
#create_close_tag ⇒ Object
returns a string with the closing tag for the element
74 75 76 |
# File 'lib/element_export.rb', line 74 def create_close_tag XMLCodec::XMLUtils::create_close_tag(elname.to_s) end |
#create_open_tag ⇒ Object
returns a string with the opening tag for the element
62 63 64 65 66 67 68 69 70 71 |
# File 'lib/element_export.rb', line 62 def create_open_tag attrs = {} self.class.each_attr do |a| value = self.send(a) if value attrs[a.to_s] = value end end XMLCodec::XMLUtils::create_open_tag(elname.to_s, attrs) end |
#create_xml(parent) ⇒ Object
Creates the xml for the element inside the parent element. The parent passed should be a Nokogiri XML Node or Document. This call is recursive creating the XML for any subelements.
7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# File 'lib/element_export.rb', line 7 def create_xml(parent) xmlel = parent.add_child Nokogiri::XML::Element.new(self.elname.to_s, parent) if self.hasvalue? xmlel.add_child self.value end create_xml_attr(xmlel) create_xml_subel(xmlel) if self.has_subelements? create_xml_subelements(xmlel) end xmlel end |
#create_xml_attr(parent) ⇒ Object
Creates the XML for the atributes
37 38 39 40 41 42 43 44 |
# File 'lib/element_export.rb', line 37 def create_xml_attr(parent) self.class.each_attr do |a| value = self.send(a) if value parent.set_attribute(a.to_s, value) end end end |
#create_xml_subel(parent) ⇒ Object
Creates the XML subelements
23 24 25 26 27 28 29 |
# File 'lib/element_export.rb', line 23 def create_xml_subel(parent) self.class.each_subel do |a| if value = self.send(a) value.create_xml(parent) end end end |
#create_xml_subelements(parent) ⇒ Object
Create the XML of the SubElements
32 33 34 |
# File 'lib/element_export.rb', line 32 def create_xml_subelements(parent) self.subelements.create_xml(parent) end |
#delete_element(element) ⇒ Object
Remove the given subelement from the element
112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/element.rb', line 112 def delete_element(element) self.class.each_subel do |a| value = self.send(a) if self.class.subel_mult? a value.delete_element(element) else self.send(a.to_s+'=', nil) if value == element end end if has_subelements? @subelements.delete_element(element) end end |
#end_partial_export(file) ⇒ Object
Ends the partial exporting of the element.
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/element_partial_export.rb', line 47 def end_partial_export(file) if not already_partial_export_ended? @already_partial_export_ended = true if not already_partial_exported? raise "<#{self} Trying to end the export of an element that hasn't"+ " been started yet" end each_subelement do |e| e.end_partial_export(file) end file << create_close_tag if self.__parent self.__parent.delete_element(self) end end end |
#has_subelements? ⇒ Boolean
7 |
# File 'lib/element_subelements.rb', line 7 def has_subelements?; self.class.has_subelements? end |
#hasvalue? ⇒ Boolean
6 |
# File 'lib/element_value.rb', line 6 def hasvalue?; self.class.hasvalue? end |
#partial_export(file) ⇒ Object
Export this element into a file. Will also start to export the parents of the element. It’s equivalent to calling start_partial_export followed by end_partial_export.
18 19 20 21 22 23 |
# File 'lib/element_partial_export.rb', line 18 def partial_export(file) if not already_partial_exported? start_partial_export(file) end_partial_export(file) end end |
#start_partial_export(file) ⇒ Object
Starts to export the element to a file. all the existing elements will be exported. After calling this you should only add stuff that you will export explicitly by calling partial_export or start_partial_export.
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/element_partial_export.rb', line 28 def start_partial_export(file) if not already_partial_exported? @already_partial_exported = true if self.__parent self.__parent.start_partial_export(file) end file << create_open_tag if self.hasvalue? file << XMLCodec::XMLUtils::escape_xml(self.value) end each_subelement do |e| e.partial_export(file) end end end |
#xml_text ⇒ Object
create the XML text of the element
47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/element_export.rb', line 47 def xml_text str = create_open_tag if self.hasvalue? str << XMLCodec::XMLUtils::escape_xml(self.value) end each_subelement do |e| str << e.xml_text end str << create_close_tag str end |