jueves, 12 de septiembre de 2013

Terminamos el proyecto

Esto se va acabando


Sólo nos queda un método. El dichoso “findEndOfTag” que nos indica donde acaba un elemento. Para ello tenemos que pasarle como parámetro la posición en que comienza dicho elemento:

def findEndOfTag(start)
  if @nodes == nil
   raise 'Not initialized'
  end

  lasttag = @nodes.length - 1
  ending = lasttag

  if @nodes[start].class.name != "HTMLTag"
   ending = start
  elsif isClosed?(start)
   ending = start
  else
   tname = @nodes[start].name
   tagsfound = 0
   (start..lasttag).each do |x|
    if @nodes[x].class.name == "HTMLTag"

       and @nodes[x].name == tname
       and not isClosed?(x)
         tagsfound += 1
    elsif @nodes[x].class.name == "HTMLClose" and @nodes[x].name == tname
         tagsfound -= 1
    end

    if tagsfound == 0
     ending = x
     break
    end
   end
  end


  return ending

end

Para empezar, asumimos que, si no demostramos otra cosa, el objeto acabará al final del documento:

lasttag = @nodes.length - 1
ending = lasttag

Ahora bien, los elementos que no son etiquetas HTML sólo tienen un nodo. O sea: acaban donde empiezan. Y lo mismo ocurre con las etiquetas HTML que, como mencionamos anteriormente y por una u otra razón, se autocierran:

if @nodes[start].class.name != "HTMLTag"
  ending = start
elsif isClosed?(start)
  ending = start

En otro caso, miraremos uno a uno los nodos a partir de la apertura de la etiqueta. Hay que tener en cuenta que podemos encontrarnos con etiquetas del mismo nombre de forma anidada, como en:

<div>
abcde <div id=abcde> HOLA </div>
</div>

… así que anotamos el nombre de la etiqueta cuyo final andamos buscando y llevamos la cuenta de cuántas etiquetas de apertura no autocerradas y cuántas etiquetas de cierre vamos encontrando con el mismo nombre.

tname = @nodes[start].name
tagsfound = 0
(start..lasttag).each do |x|
  if @nodes[x].class.name == "HTMLTag"
    and @nodes[x].name == tname
    and not isClosed?(x)
      tagsfound += 1
  elsif @nodes[x].class.name == "HTMLClose" and @nodes[x].name == tname
      tagsfound -= 1
  end



Cuando el número de aperturas y de cierres sea el mismo hemos encontrado el final y podemos salir del bucle. Precisamente para eso es para lo que sirve la instrucción “break”:

if tagsfound == 0
  ending = x
  break

Y tras cerrar con sus correspondientes “end” todo lo que hemos ido abriendo, retornamos la posición en que acaba la etiqueta:

 
return ending

 

Chin pon


¡Eh! ¡Espera!

 
Aún no hemos acabado. Que no se nos olvide poner un último “end”. El que cierra la definición de la clase:

 
end # class HtmlDoc


Ahora sí. Ya podemos sacar conclusiones.

La clase HTMLDoc supone un paso más de abstracción en la representación de documentos HTML. Un paso que, gracias al paradigma de la programación orientada a objetos, se aprovecha del trabajo que ya habíamos hecho con clases como HTMLParser.


Ahora podremos hacer programas más resultones. Y nos costará mucho menos trabajo.

Aunque, claro, está muy bien eso de poder gestionar el código HTML, pero... ¿de donde lo sacamos? Creo que estaréis de acuerdo en que es de los servidores web de donde uno suele conseguir código HTML más frecuentemente. Así que necesitaremos una clase que interactúe con ellos.

Pero eso es otra historia








No hay comentarios:

Publicar un comentario