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
135 136 137 |
# File 'lib/om/xml/dynamic_node.rb', line 135 def !=(other) val != other end |
#==(other) ⇒ Object
131 132 133 |
# File 'lib/om/xml/dynamic_node.rb', line 131 def ==(other) other == val end |
#delete ⇒ Object
123 124 125 |
# File 'lib/om/xml/dynamic_node.rb', line 123 def delete nodeset.delete end |
#eql?(other) ⇒ Boolean
139 140 141 |
# File 'lib/om/xml/dynamic_node.rb', line 139 def eql?(other) self == other end |
#inspect ⇒ Object
127 128 129 |
# File 'lib/om/xml/dynamic_node.rb', line 127 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
117 118 119 120 121 |
# File 'lib/om/xml/dynamic_node.rb', line 117 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
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/om/xml/dynamic_node.rb', line 173 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
100 101 102 103 104 105 106 |
# File 'lib/om/xml/dynamic_node.rb', line 100 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
143 144 145 146 147 148 149 |
# File 'lib/om/xml/dynamic_node.rb', line 143 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
110 111 112 113 114 115 |
# File 'lib/om/xml/dynamic_node.rb', line 110 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 94 95 96 97 |
# 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 = if parent parent.to_pointer elsif term.is_a? NamedTermProxy term.proxy_pointer[0..-2] end @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
151 152 153 154 155 156 157 158 159 |
# File 'lib/om/xml/dynamic_node.rb', line 151 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 |