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
and
@nodes[x].name == tname
tagsfound = 0 (start..lasttag).each do |x| if @nodes[x].class.name == "HTMLTag" 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 |
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