10.4. Encontrar hijos directos de un nodo

Otra técnica útil cuando se analizan documentos XML es encontrar todos los elementos que sean hijos directos de un elemento en particular. Por ejemplo, en los ficheros de gramáticas un elemento ref puede tener varios elementos p, cada uno de los cuales puede contener muchas cosas, incluyendo otros elementos p. Queremos encontrar sólo los elementos p que son hijos de ref, no elementos p que son hijos de otros elementos p.

Quizá piense que podría simplemente usar getElementsByTagName para esto, pero no puede. getElementsByTagName busca de forma recursiva y devuelve una lista con todos los elementos que encuentra. Como los elementos p pueden contener otros p, no podemos usar getElementsByTagName porque podría devolver elementos p anidados que no queremos. Para encontrar sólo elementos hijos directos tendremos que hacerlo por nosotros mismos.

Ejemplo 10.16. Búsqueda de elementos hijos directos

    def randomChildElement(self, node):
        choices = [e for e in node.childNodes
                   if e.nodeType == e.ELEMENT_NODE] 1 2 3
        chosen = random.choice(choices)             4
        return chosen                              
1 Como vio en Ejemplo 9.9, “Obtener nodos hijos”, el atributo childNodes devuelve una lista de todos los nodos hijos de un elemento.
2 Sin embargo, como vio en Ejemplo 9.11, “Los nodos hijos pueden ser un texto”, la lista que devuelve childNodes contiene todos los tipos diferentes de nodos, incluidos nodos de texto. Esto no es lo que queremos. Sólo queremos los hijos que sean elementos.
3 Cada nodo tiene un atributo nodeType que puede ser ELEMENT_NODE, TEXT_NODE, COMMENT_NODE y otros valores. La lista completa de posibles valores está en el fichero __init__.py del paquete xml.dom (en Sección 9.2, “Paquetes” hablamos de los paquetes). Pero sólo nos interesan los nodos que son elementos, así que podemos filtrar la lista para incluir sólo los nodos cuyo nodeType es ELEMENT_NODE.
4 Una vez tenemos la lista de los elementos, escoger uno al azar es sencillo. Python viene con un módulo llamado random que incluye varias funciones útiles. La función random.choice toma una lista de cualquier número de elementos y devuelve uno al azar. Por ejemplo, si los elementos ref contienen varios elementos p entonces choices podría ser una lista de elementos p y chosen terminaría siendo uno de ellos, escogido al azar.