Hpricot::Traverse

Public Class Methods

filter(tok, &blk) click to toggle source
     # File lib/hpricot/elements.rb, line 371
371:     def self.filter(tok, &blk)
372:       define_method("filter[#{tok.is_a?(String) ? tok : tok.inspect}]", &blk)
373:     end

Public Instance Methods

%(expr) click to toggle source
Alias for: at
/(expr, &blk) click to toggle source
Alias for: search
after(html = nil, &blk) click to toggle source

Adds elements immediately after this element, contained in the html string.

     # File lib/hpricot/traverse.rb, line 121
121:     def after(html = nil, &blk)
122:       parent.insert_after(make(html, &blk), self)
123:     end
at(expr) click to toggle source

Find the first matching node for the CSS or XPath expr string.

     # File lib/hpricot/traverse.rb, line 341
341:     def at(expr)
342:       search(expr).first
343:     end
Also aliased as: %
before(html = nil, &blk) click to toggle source

Adds elements immediately before this element, contained in the html string.

     # File lib/hpricot/traverse.rb, line 126
126:     def before(html = nil, &blk)
127:       parent.insert_before(make(html, &blk), self)
128:     end
bogusetag?() click to toggle source

Is this object a stranded end tag?

    # File lib/hpricot/traverse.rb, line 21
21:     def bogusetag?() BogusETag::Trav === self end
children_of_type(tag_name) click to toggle source

Find children of a given tag_name.

  ele.children_of_type('p')
    #=> [...array of paragraphs...]
     # File lib/hpricot/traverse.rb, line 390
390:     def children_of_type(tag_name)
391:       if respond_to? :children
392:         children.find_all do |x|
393:           x.respond_to?(:pathname) && x.pathname == tag_name
394:         end
395:       end
396:     end
clean_path(path) click to toggle source
     # File lib/hpricot/traverse.rb, line 203
203:     def clean_path(path)
204:       path.gsub(/^\s+|\s+$/, '')
205:     end
comment?() click to toggle source

Is this object a comment?

    # File lib/hpricot/traverse.rb, line 19
19:     def comment?() Comment::Trav === self end
css_path() click to toggle source

Builds a unique CSS string for this node, from the root of the document containing it.

     # File lib/hpricot/traverse.rb, line 226
226:     def css_path
227:       if elem? and has_attribute? 'id'
228:         "##{get_attribute('id')}"
229:       else
230:         sim, i, id = 0, 0, 0
231:         parent.children.each do |e|
232:           id = sim if e == self
233:           sim += 1 if e.pathname == self.pathname
234:         end if parent.children
235:         p = parent.css_path
236:         p = p ? "#{p} > #{self.pathname}" : self.pathname
237:         p += ":nth(#{id})" if sim >= 2
238:         p
239:       end
240:     end
doc?() click to toggle source

Is this object the enclosing HTML or XML document?

   # File lib/hpricot/traverse.rb, line 7
7:     def doc?() Doc::Trav === self end
doctype?() click to toggle source

Is this object a doctype tag?

    # File lib/hpricot/traverse.rb, line 15
15:     def doctype?() DocType::Trav === self end
elem?() click to toggle source

Is this object an HTML or XML element?

   # File lib/hpricot/traverse.rb, line 9
9:     def elem?() Elem::Trav === self end
following() click to toggle source

Find all nodes which follow the current one.

     # File lib/hpricot/traverse.rb, line 114
114:     def following
115:       sibs = parent.children 
116:       si = sibs.index(self) + 1 
117:       return Elements[*sibs[si...sibs.length]] 
118:     end
get_subnode(*indexes) click to toggle source
     # File lib/hpricot/traverse.rb, line 138
138:     def get_subnode(*indexes)
139:       n = self
140:       indexes.each {|index|
141:         n = n.get_subnode_internal(index)
142:       }
143:       n
144:     end
html(inner = nil, &blk) click to toggle source

Builds an HTML string from the contents of this node.

     # File lib/hpricot/traverse.rb, line 168
168:     def html(inner = nil, &blk)
169:       if inner or blk
170:         altered!
171:         case inner
172:         when Array
173:           self.children = inner
174:         else
175:           self.children = make(inner, &blk)
176:         end
177:         reparent self.children
178:       else
179:         if respond_to?(:children) and children
180:           children.map { |x| x.output("") }.join
181:         else
182:           ""
183:         end
184:       end
185:     end
Also aliased as: inner_html
index(name) click to toggle source
    # File lib/hpricot/traverse.rb, line 47
47:     def index(name)
48:       i = 0
49:       return i if name == "*"
50:       children.each do |x|
51:         return i if (x.respond_to?(:name) and name == x.name) or
52:           (x.text? and name == "text()")
53:         i += 1
54:       end if children
55:       1
56:     end
innerHTML(inner = nil, &blk) click to toggle source
Alias for: inner_html
innerHTML=(inner) click to toggle source
Alias for: inner_html=
innerText() click to toggle source
Alias for: inner_text
inner_html(inner = nil, &blk) click to toggle source
Also aliased as: innerHTML
Alias for: html
inner_html=(inner) click to toggle source

Inserts new contents into the current node, based on the HTML contained in string inner.

     # File lib/hpricot/traverse.rb, line 191
191:     def inner_html=(inner)
192:       html(inner || [])
193:     end
Also aliased as: innerHTML=
inner_text() click to toggle source

Builds a string from the text contained in this node. All HTML elements are removed.

     # File lib/hpricot/traverse.rb, line 158
158:     def inner_text
159:       if respond_to?(:children) and children
160:         children.map { |x| x.inner_text }.join
161:       else
162:         ""
163:       end
164:     end
Also aliased as: innerText
make(input = nil, &blk) click to toggle source

Parses an HTML string, making an HTML fragment based on the options used to create the container document.

    # File lib/hpricot/traverse.rb, line 25
25:     def make(input = nil, &blk)
26:       if parent and parent.respond_to? :make
27:         parent.make(input, &blk)
28:       else
29:         Hpricot.make(input, &blk).children
30:       end
31:     end
next() click to toggle source

Returns the node neighboring this node to the south: just below it. This method includes text nodes and comments and such.

    # File lib/hpricot/traverse.rb, line 91
91:     def next
92:       sib = parent.children
93:       sib[sib.index(self) + 1] if parent
94:     end
Also aliased as: next_node
next_node() click to toggle source
Alias for: next
node_position() click to toggle source
     # File lib/hpricot/traverse.rb, line 242
242:     def node_position
243:       parent.children.index(self)
244:     end
nodes_at(*pos) click to toggle source

Puts together an array of neighboring nodes based on their proximity to this node. So, for example, to get the next node, you could use nodes_at(1). Or, to get the previous node, use <tt>nodes_at(1).

This method also accepts ranges and sets of numbers.

   ele.nodes_at(-3..-1, 1..3) # gets three nodes before and three after
   ele.nodes_at(1, 5, 7) # gets three nodes at offsets below the current node
   ele.nodes_at(0, 5..6) # the current node and two others
    # File lib/hpricot/traverse.rb, line 67
67:     def nodes_at(*pos)
68:       sib = parent.children
69:       i, si = 0, sib.index(self)
70:       pos.map! do |r|
71:         if r.is_a?(Range) and r.begin.is_a?(String)
72:           r = Range.new(parent.index(r.begin)-si, parent.index(r.end)-si, r.exclude_end?)
73:         end
74:         r
75:       end
76:       p pos
77:       Elements[*
78:         sib.select do |x|
79:           sel =
80:             case i - si when *pos
81:               true
82:             end
83:           i += 1
84:           sel
85:         end
86:       ]
87:     end
position() click to toggle source
     # File lib/hpricot/traverse.rb, line 246
246:     def position
247:       parent.children_of_type(self.pathname).index(self)
248:     end
preceding() click to toggle source

Find all preceding nodes.

     # File lib/hpricot/traverse.rb, line 107
107:     def preceding
108:       sibs = parent.children
109:       si = sibs.index(self) 
110:       return Elements[*sibs[0...si]] 
111:     end
previous() click to toggle source

Returns to node neighboring this node to the north: just above it. This method includes text nodes and comments and such.

     # File lib/hpricot/traverse.rb, line 99
 99:     def previous
100:       sib = parent.children
101:       x = sib.index(self) - 1
102:       sib[x] if sib and x >= 0
103:     end
Also aliased as: previous_node
previous_node() click to toggle source
Alias for: previous
procins?() click to toggle source

Is this object an XML processing instruction?

    # File lib/hpricot/traverse.rb, line 17
17:     def procins?() ProcIns::Trav === self end
search(expr, &blk) click to toggle source

Searches this node for all elements matching the CSS or XPath expr. Returns an Elements array containing the matching nodes. If blk is given, it is used to iterate through the matching set.

     # File lib/hpricot/traverse.rb, line 254
254:     def search(expr, &blk)
255:       if Range === expr
256:         return Elements.expand(at(expr.begin), at(expr.end), expr.exclude_end?)
257:       end
258:       last = nil
259:       nodes = [self]
260:       done = []
261:       expr = expr.to_s
262:       hist = []
263:       until expr.empty?
264:           expr = clean_path(expr)
265:           expr.gsub!(%^//!, '')
266: 
267:           case expr
268:           when %^/?\.\.!
269:               last = expr = $'
270:               nodes.map! { |node| node.parent }
271:           when %^[>/]\s*!
272:               last = expr = $'
273:               nodes = Elements[*nodes.map { |node| node.children if node.respond_to? :children }.flatten.compact]
274:           when %^\+!
275:               last = expr = $'
276:               nodes.map! do |node|
277:                   siblings = node.parent.children
278:                   siblings[siblings.index(node)+1]
279:               end
280:               nodes.compact!
281:           when %^~!
282:               last = expr = $'
283:               nodes.map! do |node|
284:                   siblings = node.parent.children
285:                   siblings[(siblings.index(node)+1)..1]
286:               end
287:               nodes.flatten!
288:           when %^[|,]!
289:               last = expr = " #$'"
290:               nodes.shift if nodes.first == self
291:               done += nodes
292:               nodes = [self]
293:           else
294:               m = expr.match(%^([#.]?)([a-z0-9\\*_-]*)!).to_a
295:               after = $'
296:               mt = after[%:[a-z0-9\\*_-]+!, 0]
297:               oop = false
298:               if mt and not (mt == ":not" or Traverse.method_defined? "filter[#{mt}]")
299:                 after = $' 
300:                 m[2] += mt
301:                 expr = after
302:               end
303:               if m[1] == '#'
304:                   oid = get_element_by_id(m[2])
305:                   nodes = oid ? [oid] : []
306:                   expr = after
307:               else
308:                   m[2] = "*" if after =~ /^\(\)/ || m[2] == "" || m[1] == "."
309:                   ret = []
310:                   nodes.each do |node|
311:                       case m[2]
312:                       when '*'
313:                           node.traverse_element { |n| ret << n }
314:                       else
315:                           if node.respond_to? :get_elements_by_tag_name
316:                             ret += [*node.get_elements_by_tag_name(m[2])] - [*(node unless last)]
317:                           end
318:                       end
319:                   end
320:                   nodes = ret
321:               end
322:               last = nil
323:           end
324: 
325:           hist << expr
326:           break if hist[1] == hist[2]
327:           nodes, expr = Elements.filter(nodes, expr)
328:       end
329:       nodes = done + nodes.flatten.uniq
330:       if blk
331:           nodes.each(&blk)
332:           self
333:       else
334:           Elements[*nodes]
335:       end
336:     end
Also aliased as: /
swap(html = nil, &blk) click to toggle source

Replace this element and its contents with the nodes contained in the html string.

     # File lib/hpricot/traverse.rb, line 133
133:     def swap(html = nil, &blk)
134:       parent.altered!
135:       parent.replace_child(self, make(html, &blk))
136:     end
text?() click to toggle source

Is this object an HTML text node?

    # File lib/hpricot/traverse.rb, line 11
11:     def text?() Text::Trav === self end
to_html() click to toggle source

Builds an HTML string from this node and its contents. If you need to write to a stream, try calling output(io) as a method on this object.

    # File lib/hpricot/traverse.rb, line 36
36:     def to_html
37:       output("")
38:     end
Also aliased as: to_s
to_original_html() click to toggle source

Attempts to preserve the original HTML of the document, only outputing new tags for elements which have changed.

    # File lib/hpricot/traverse.rb, line 43
43:     def to_original_html
44:       output("", :preserve => true)
45:     end
to_plain_text() click to toggle source

Builds a string from the text contained in this node. All HTML elements are removed.

     # File lib/hpricot/traverse.rb, line 148
148:     def to_plain_text
149:       if respond_to?(:children) and children
150:         children.map { |x| x.to_plain_text }.join.strip.gsub(/\n{2,}/, "\n\n")
151:       else
152:         ""
153:       end
154:     end
to_s() click to toggle source
Alias for: to_html
traverse_element(*names) click to toggle source

traverse_element traverses elements in the tree. It yields elements in depth first order.

If names are empty, it yields all elements. If non-empty names are given, it should be list of universal names.

A nested element is yielded in depth first order as follows.

  t = Hpricot('<a id=0><b><a id=1 /></b><c id=2 /></a>') 
  t.traverse_element("a", "c") {|e| p e}
  # =>
  {elem <a id="0"> {elem <b> {emptyelem <a id="1">} </b>} {emptyelem <c id="2">} </a>}
  {emptyelem <a id="1">}
  {emptyelem <c id="2">}

Universal names are specified as follows.

  t = Hpricot(<<'End')
  <html>
  <meta name="robots" content="index,nofollow">
  <meta name="author" content="Who am I?">    
  </html>
  End
  t.traverse_element("{http://www.w3.org/1999/xhtml}meta") {|e| p e}
  # =>
  {emptyelem <{http://www.w3.org/1999/xhtml}meta name="robots" content="index,nofollow">}
  {emptyelem <{http://www.w3.org/1999/xhtml}meta name="author" content="Who am I?">}
     # File lib/hpricot/traverse.rb, line 374
374:     def traverse_element(*names, &block) # :yields: element
375:       if names.empty?
376:         traverse_all_element(&block)
377:       else
378:         name_set = {}
379:         names.each {|n| name_set[n] = true }
380:         traverse_some_element(name_set, &block)
381:       end
382:       nil
383:     end
traverse_text() click to toggle source

traverse_text traverses texts in the tree

     # File lib/hpricot/traverse.rb, line 680
680:     def traverse_text(&block) # :yields: text
681:       traverse_text_internal(&block)
682:       nil
683:     end
xmldecl?() click to toggle source

Is this object an XML declaration?

    # File lib/hpricot/traverse.rb, line 13
13:     def xmldecl?() XMLDecl::Trav === self end
xpath() click to toggle source

Builds a unique XPath string for this node, from the root of the document containing it.

     # File lib/hpricot/traverse.rb, line 209
209:     def xpath
210:       if elem? and has_attribute? 'id'
211:         "//#{self.name}[@id='#{get_attribute('id')}']"
212:       else
213:         sim, id = 0, 0, 0
214:         parent.children.each do |e|
215:           id = sim if e == self
216:           sim += 1 if e.pathname == self.pathname
217:         end if parent.children
218:         p = File.join(parent.xpath, self.pathname)
219:         p += "[#{id+1}]" if sim >= 2
220:         p
221:       end
222:     end

Private Instance Methods

reparent(nodes) click to toggle source
     # File lib/hpricot/traverse.rb, line 196
196:     def reparent(nodes)
197:       return unless nodes
198:       altered!
199:       [*nodes].each { |e| e.parent = self }
200:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.