class XMLRegistry
Attributes
Public Class Methods
# File lib/xml-registry.rb, line 26 def initialize(template = '<root></root>', debug: false) @debug = debug super() @template, _ = RXFHelper.read(template) @doc = Rexle.new(@template) end
Public Instance Methods
# File lib/xml-registry.rb, line 118 def [](path) s = path.split('/').map {|x| x.is_number? ? x.prepend('x') : x}.join '/' @doc.root.element s end
# File lib/xml-registry.rb, line 62 def []=(path, val) s = path.split('/').map {|x| x[0].is_number? ? x.prepend('x') : x}.join '/' self.set_key(s, val) end
delete the key at the specified path example: delete_key
'app/gtd/funday'
# File lib/xml-registry.rb, line 127 def delete_key(path) @doc.root.delete path end
Export the registry to file if the filepath is specified. Regardless, the registry will be returned as a string in the registry export format.
# File lib/xml-registry.rb, line 231 def export(s=nil) reg = print_scan(@doc.root).join("\n") # jr 250118 File.open(s){|f| f.write reg} if s RXFHelper.write(s, reg) if s reg end
get the key value by passing the path example: get_key
('app/gtd/funday').value #=> 'friday'
returns the value as a Rexle::Element
# File lib/xml-registry.rb, line 72 def get_key(path) key = @doc.root.element path raise ("xml-registry: key %s not found" % path) unless key key.instance_eval { @path = path def to_h(e) v = if e.has_elements? then e.elements.inject({}) do |r, x| r.merge to_h(x) end else e.text end {e.name => v} end def to_config() SimpleConfig.new(to_h(self), attributes: {key: @path}) end def to_kvx() Kvx.new(to_h(self), attributes: {key: @path}) end def to_os() OpenStruct.new(to_h(self).first.last) end } key end
get several keys using a Rexle XPath example: get_keys
('//funday') #=> [<funday>tuesday</funday>,<funday>friday</funday>]
returns an array of 0 or more Rexle elements
# File lib/xml-registry.rb, line 114 def get_keys(path) @doc.root.xpath(path) end
import a registry hive from a string in registry format example:
s =<<REG
- app/app1
-
“admin”=“jrobertson” “pin-no”=“1234”
- app/app2
-
“admin”=“dsmith” “pin-no”=“4321” REG
reg =
XMLRegistry.new
reg.import s
# File lib/xml-registry.rb, line 174 def import(s) r = RXFHelper.read(s) reg_buffer = r.first raise "read file error" unless reg_buffer if reg_buffer.strip[/^\[/] then reg_items = reg_buffer.gsub(/\n/,'').split(/(?=\[.[^\]]+\])/).map do |x| [x[/^\[(.[^\]]+)\]/,1], Hash[*($').scan(/"([^"]+)"="(.[^"]*)"/).flatten]] end elsif reg_buffer.strip.lines.grep(/^\s+\w/).any? puts 'hierachical import' if @debug doc = LineTree.new(reg_buffer).to_doc reg_items = [] doc.root.each_recursive do |e| puts 'e: ' + e.inspect if @debug if e.is_a?(Rexle::Element) and e.children.length < 2 then reg_items << [e.backtrack.to_xpath.sub(/^root\//,'')\ .sub(/\/[^\/]+$/,''), {e.name => e.text }] end end else reg_items = reg_buffer.split(/(?=^[^:]+$)/).map do |raw_section| lines = raw_section.lines.to_a next if lines.first.strip.empty? path = lines.shift.rstrip [path, Hash[lines.map{|x| x.split(':',2).map(&:strip)}]] end reg_items.compact! end puts 'reg_items: ' + reg_items.inspect if @debug reg_items.each do |path, items| items.each {|k,value| self.set_key("%s/%s" % [path,k], value)} end :import end
Creates a new registry document from scratch. Optional param: string XML template example: initialise_registry
('<root><app/></root>')
# File lib/xml-registry.rb, line 37 def initialise_registry(new_template=nil) @doc = Rexle.new(new_template || @template) end
load a new registry xml document replacing the existing registry
# File lib/xml-registry.rb, line 146 def load_xml(s='') @doc = Rexle.new(RXFHelper.read(s)[0]) self end
save the registry to the specified file path
# File lib/xml-registry.rb, line 153 def save(s) RXFHelper.write s, @doc.xml(pretty: true) end
Set the key by passing in the path and the value example: set_key
'app/gtd/funday', 'friday'
# File lib/xml-registry.rb, line 47 def set_key(path, value) # if the 1st element doesn't exist create it e = path.split('/',2).first @doc.root.add_element Rexle::Element.new(e) unless @doc.root.element e create_path = find_path(path) if not create_path.empty? then parent_path = (path.split('/') - create_path.reverse).join('/') key_builder(parent_path, create_path) end add_value(path, value) end
# File lib/xml-registry.rb, line 93 def to_config() SimpleConfig.new(to_h(self), attributes: {key: @path}) end
# File lib/xml-registry.rb, line 80 def to_h(e) v = if e.has_elements? then e.elements.inject({}) do |r, x| r.merge to_h(x) end else e.text end {e.name => v} end
# File lib/xml-registry.rb, line 97 def to_kvx() Kvx.new(to_h(self), attributes: {key: @path}) end
# File lib/xml-registry.rb, line 101 def to_os() OpenStruct.new(to_h(self).first.last) end
return the registry as an XML document example: puts reg.to_xml pretty: true
# File lib/xml-registry.rb, line 134 def to_xml(options={}) @doc.xml options end
# File lib/xml-registry.rb, line 140 def xml(options={}) @doc.root.xml options end
# File lib/xml-registry.rb, line 238 def xpath(s) @doc.root.xpath s end
Private Instance Methods
# File lib/xml-registry.rb, line 244 def add_key(path='app', key='untitled') node = @doc.root.element path r = node.add_element Rexle::Element.new(key) r end
# File lib/xml-registry.rb, line 250 def add_value(key, value) @doc.root.element(key).text = value end
# File lib/xml-registry.rb, line 254 def find_path(path, create_path=[]) return create_path if !@doc.root.xpath(path).empty? apath = path.split('/') create_path << apath.pop find_path(apath.join('/'), create_path) end
# File lib/xml-registry.rb, line 262 def key_builder(parent_path, create_path) key = create_path.pop add_key(parent_path, key) key_builder("#{parent_path}/#{key}", create_path) unless create_path.empty? end
# File lib/xml-registry.rb, line 268 def print_scan(node, parent=[]) out = [] parent << node.name items = [] node.elements.each do |e| if e.has_elements? then out << print_scan(e, parent.clone) else items << [e.name, e.text] end end if parent.length > 1 and items.length > 0 then out << "[%s]\n%s\n" % [parent[1..-1].join("/"), items.map {|x| "\"%s\"=\"%s\"" % x}.join("\n")] end out end