Class: OM::XML::DynamicNode
- Inherits:
-
Object
- Object
- OM::XML::DynamicNode
- Defined in:
- lib/om/xml/dynamic_node.rb
Overview
Provides a natural syntax for using OM Terminologies to access values from xml Documents
Note: All of these examples assume that @article is an instance of OM::Samples::ModsArticle. Look at that file to see the Terminology.
Defined Under Namespace
Classes: AddressedNode
Instance Attribute Summary collapse
-
#addressed_node ⇒ Object
Returns the value of attribute addressed_node.
-
#index ⇒ Object
Returns the value of attribute index.
-
#key ⇒ Object
Returns the value of attribute key.
-
#parent ⇒ Object
Returns the value of attribute parent.
-
#term ⇒ Object
Returns the value of attribute term.
Instance Method Summary collapse
- #!=(other) ⇒ Object
- #==(other) ⇒ Object
- #delete ⇒ Object
- #eql?(other) ⇒ Boolean
-
#initialize(key, index, document, term, parent = nil) ⇒ DynamicNode
constructor
TODO a real term object in here would make it easier to lookup.
- #inspect ⇒ Object
- #method_missing(name, *args, &block) ⇒ Object
- #new_update_node(name, args) ⇒ Object
- #new_update_node_with_index(name, args) ⇒ Object
- #nodeset ⇒ Object
- #respond_to?(method) ⇒ Boolean
-
#retrieve_addressed_node ⇒ Object
This is very similar to Terminology#retrieve_term, however it expands proxy paths out into their cannonical paths.
- #term_child_by_name(term, name) ⇒ Object
- #to_pointer ⇒ Object
-
#val ⇒ Array
This resolves the target of this dynamic node into a reified Array.
- #val=(args) ⇒ Object
- #xpath ⇒ Object
Constructor Details
#initialize(key, index, document, term, parent = nil) ⇒ DynamicNode
TODO a real term object in here would make it easier to lookup
33 34 35 36 37 38 39 |
# File 'lib/om/xml/dynamic_node.rb', line 33 def initialize(key, index, document, term, parent=nil) ##TODO a real term object in here would make it easier to lookup self.key = key self.index = index @document = document self.term = term self.parent = parent end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, &block) ⇒ Object
41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/om/xml/dynamic_node.rb', line 41 def method_missing (name, *args, &block) if /=$/.match(name.to_s) new_update_node(name, args) elsif args.length > 1 new_update_node_with_index(name, args) else child = term_child_by_name(term.nil? ? parent.term : term, name) if child OM::XML::DynamicNode.new(name, args.first, @document, child, self) else val.send(name, *args, &block) end end end |
Instance Attribute Details
#addressed_node ⇒ Object
Returns the value of attribute addressed_node.
32 33 34 |
# File 'lib/om/xml/dynamic_node.rb', line 32 def addressed_node @addressed_node end |
#index ⇒ Object
Returns the value of attribute index.
32 33 34 |
# File 'lib/om/xml/dynamic_node.rb', line 32 def index @index end |
#key ⇒ Object
Returns the value of attribute key.
32 33 34 |
# File 'lib/om/xml/dynamic_node.rb', line 32 def key @key end |
#parent ⇒ Object
Returns the value of attribute parent.
32 33 34 |
# File 'lib/om/xml/dynamic_node.rb', line 32 def parent @parent end |
#term ⇒ Object
Returns the value of attribute term.
32 33 34 |
# File 'lib/om/xml/dynamic_node.rb', line 32 def term @term end |
Instance Method Details
#!=(other) ⇒ Object
131 132 133 |
# File 'lib/om/xml/dynamic_node.rb', line 131 def !=(other) val != other end |
#==(other) ⇒ Object
127 128 129 |
# File 'lib/om/xml/dynamic_node.rb', line 127 def ==(other) other == val end |
#delete ⇒ Object
119 120 121 |
# File 'lib/om/xml/dynamic_node.rb', line 119 def delete nodeset.delete end |
#eql?(other) ⇒ Boolean
135 136 137 |
# File 'lib/om/xml/dynamic_node.rb', line 135 def eql?(other) self == other end |
#inspect ⇒ Object
123 124 125 |
# File 'lib/om/xml/dynamic_node.rb', line 123 def inspect val.inspect end |
#new_update_node(name, args) ⇒ Object
60 61 62 63 64 65 |
# File 'lib/om/xml/dynamic_node.rb', line 60 def new_update_node(name, args) modified_name = name.to_s.chop.to_sym child = term.retrieve_term(modified_name) node = OM::XML::DynamicNode.new(modified_name, nil, @document, child, self) node.val=args end |
#new_update_node_with_index(name, args) ⇒ Object
67 68 69 70 71 72 |
# File 'lib/om/xml/dynamic_node.rb', line 67 def new_update_node_with_index(name, args) index = args.shift child = term.retrieve_term(name) node = OM::XML::DynamicNode.new(name, index, @document, child, self) node.val=args end |
#nodeset ⇒ Object
113 114 115 116 117 |
# File 'lib/om/xml/dynamic_node.rb', line 113 def nodeset query = xpath trim_text = !query.index("text()").nil? return @document.find_by_xpath(query) end |
#respond_to?(method) ⇒ Boolean
56 57 58 |
# File 'lib/om/xml/dynamic_node.rb', line 56 def respond_to?(method) super || val.respond_to?(method) end |
#retrieve_addressed_node ⇒ Object
This is very similar to Terminology#retrieve_term, however it expands proxy paths out into their cannonical paths
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
# File 'lib/om/xml/dynamic_node.rb', line 169 def retrieve_addressed_node() chain = [] if parent chain += parent.retrieve_addressed_node() end if (self.index) ### This is an index node = AddressedNode.new(key, term.xpath_relative, self) node.xpath = OM::XML::TermXpathGenerator.add_node_index_predicate(node.xpath, index) chain << node elsif (term.kind_of? NamedTermProxy) proxy = term.proxy_pointer.dup first = proxy.shift p = @document.class.terminology.retrieve_node(*first) chain << AddressedNode.new(p, p.xpath_relative, self) while !proxy.empty? first = proxy.shift p = p.retrieve_term(first) chain << AddressedNode.new(p, p.xpath_relative, self) end else chain << AddressedNode.new(key, term.xpath_relative, self) end chain end |
#term_child_by_name(term, name) ⇒ Object
96 97 98 99 100 101 102 |
# File 'lib/om/xml/dynamic_node.rb', line 96 def term_child_by_name(term, name) if (term.kind_of? NamedTermProxy) @document.class.terminology.retrieve_node(*(term.proxy_pointer.dup << name)) else term.retrieve_term(name) end end |
#to_pointer ⇒ Object
139 140 141 142 143 144 145 |
# File 'lib/om/xml/dynamic_node.rb', line 139 def to_pointer if self.index parent.nil? ? [{key => index}] : parent.to_pointer << {key => index} else ### A pointer parent.nil? ? [key] : parent.to_pointer << key end end |
#val ⇒ Array
This resolves the target of this dynamic node into a reified Array
106 107 108 109 110 111 |
# File 'lib/om/xml/dynamic_node.rb', line 106 def val query = xpath trim_text = !query.index("text()").nil? val = @document.find_by_xpath(query).collect {|node| (trim_text ? node.text.strip : node.text) } term.deserialize(val) end |
#val=(args) ⇒ Object
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/om/xml/dynamic_node.rb', line 74 def val=(args) @document.ng_xml_will_change! new_values = term.sanitize_new_values(args.first) existing_nodes = @document.find_by_xpath(xpath) if existing_nodes.length > new_values.length starting_index = new_values.length + 1 starting_index.upto(existing_nodes.size).each do |index| @document.term_value_delete select: xpath, child_index: index end end new_values.each_with_index do |z, y| ## If we pass something that already has an index on it, we should be able to add it. if existing_nodes[y.to_i].nil? parent_pointer = parent ? parent.to_pointer : nil @document.term_values_append(:parent_select=> parent_pointer,:parent_index=>0,:template=>to_pointer,:values=>z) else @document.term_value_update(xpath, y.to_i, z) end end end |
#xpath ⇒ Object
147 148 149 150 151 152 153 154 155 |
# File 'lib/om/xml/dynamic_node.rb', line 147 def xpath if parent.nil? @document.class.terminology.xpath_with_indexes(*(to_pointer << {})) ### last element is always filters else chain = retrieve_addressed_node( ) '//' + chain.map { |n| n.xpath}.join('/') end end |