Class: XmlLens
- Inherits:
-
Object
- Object
- XmlLens
- Defined in:
- lib/puppet/provider/xmlfile/lens.rb
Overview
XMLLens wraps around rexml/document and XPath to provide augeas esque-manipulation of an xml file.
Instance Method Summary collapse
-
#clear(path) ⇒ Object
Clears an element.
-
#evaluate ⇒ Object
Evaluates.
-
#get(match, expr, value, attr) ⇒ Object
Checks if a match has a certain value(attribute or text).
-
#initialize(xml, changes = nil, conditions = nil) ⇒ XmlLens
constructor
Initialized with the file(preloaded), any changes and any conditions.
-
#match(match, xml = @xml) ⇒ Object
Wrap around XPath.match.
-
#rm(path) ⇒ Object
Deletes a node.
-
#set(element, value, attribute, path) ⇒ Object
Sets a node or node attribute to a value.
-
#sort(element, attr, type) ⇒ Object
Type is ignored for now as I didn’t really have a use case for it.
Constructor Details
#initialize(xml, changes = nil, conditions = nil) ⇒ XmlLens
Initialized with the file(preloaded), any changes and any conditions
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/puppet/provider/xmlfile/lens.rb', line 7 def initialize(xml, changes = nil, conditions = nil) raise ArgumentError unless xml.is_a? REXML::Document @xml = xml @operations = Array.new @validations = Array.new # Initialize our ops and validations # these get batched and executed en-masse unless changes.nil? if changes.is_a? Array changes.each { |change| parser(change) } elsif changes.is_a? String parser(changes) else raise ArgumentError end end unless conditions.nil? if conditions.is_a? Array conditions.each { |condition| parser(condition) } elsif conditions.is_a? String parser(conditions) end end end |
Instance Method Details
#clear(path) ⇒ Object
Clears an element
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/puppet/provider/xmlfile/lens.rb', line 54 def clear(path) puts "clear #{path.inspect}" if path.is_a? Array path.each do |p| p.elements.each do |child| p.elements.delete(child) end p.text = nil p.attributes.keys.each do |key| p.attributes.delete(key) end end elsif path.is_a? REXML::Element path.elements.each do |child| path.elements.delete(child) end path.text = nil path.attributes.keys.each do |key| path.attributes.delete(key) end else raise ArgumentError end end |
#evaluate ⇒ Object
Evaluates. Calls the procs that have been loaded.
40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/puppet/provider/xmlfile/lens.rb', line 40 def evaluate # First up validations @validations.each do |validate| next if validate.call return @xml end # Those passed, so next up is actual operations @operations.each do |operation| operation.call end return @xml end |
#get(match, expr, value, attr) ⇒ Object
Checks if a match has a certain value(attribute or text)
80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/puppet/provider/xmlfile/lens.rb', line 80 def get(match, expr, value, attr) retval = false match.each do |m| if attr and attr.length > 0 retval = evaluate_expression(m.attributes[attr], expr, value) else retval = evaluate_expression(m.text, expr, value) end break if retval end return retval end |
#match(match, xml = @xml) ⇒ Object
Wrap around XPath.match
35 36 37 |
# File 'lib/puppet/provider/xmlfile/lens.rb', line 35 def match(match, xml = @xml) REXML::XPath.match(xml, match) end |
#rm(path) ⇒ Object
Deletes a node
94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/puppet/provider/xmlfile/lens.rb', line 94 def rm(path) if path.is_a? Array path.each do |p| p.parent.elements.delete(p) if p.parent end elsif path.is_a? REXML::Element path.parent.elements.delete(p) if path.parent else raise ArgumentError end end |
#set(element, value, attribute, path) ⇒ Object
Sets a node or node attribute to a value. Creates it if it doesn’t exist
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/puppet/provider/xmlfile/lens.rb', line 107 def set(element, value, attribute, path) unless element.nil? set_element = element.first else built_path = build_path(path.scan(/\/([^\[\/]*)(\[[^\]\[]*\])?+/)) if built_path[:exists] set_element = built_path[:final_path].first else set_element = built_path[:final_path].first built_path[:remainder].each do |add| set_element = set_element.elements.add(add) end end end if attribute set_element.attributes[attribute] = value else set_element.text = value end end |
#sort(element, attr, type) ⇒ Object
Type is ignored for now as I didn’t really have a use case for it.
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/puppet/provider/xmlfile/lens.rb', line 129 def sort(element, attr, type) if element.is_a?(Array) element.each do |elem| case attr when "text" sorted = elem.elements.sort { |e1, e2| e1.text <=> e2.text } when nil sorted = elem.elements.sort { |e1, e2| e1.name <=> e2.name } else sorted = elem.elements.sort { |e1, e2| e1.attributes[attr] <=> e2.attributes[attr] } end elem.elements.each { |a| elem.elements.delete(a) } sorted.each { |a| elem.add_element(a) } end elsif element.is_a? REXML::Element case attr when "text" sorted = elem.elements.sort { |e1, e2| e1.text <=> e2.text } when nil sorted = elem.elements.sort { |e1, e2| e1.name <=> e2.name } else sorted = elem.elements.sort { |e1, e2| e1.attributes[attr] <=> e2.attributes[attr] } end element.elements.each { |a| element.elements.delete(a) } sorted.each { |a| element.add_element(a) } end end |