6.10. Trovare i figli diretti di un nodo

Un'altra utile tecnica quando analiziamo documenti XML consiste nel trovare tutti gli elementi figli diretti di un particolare elemento. Per esempio, nel nostro file grammar, un elemento ref può avere alcuni elementi p, ognuno dei quali può contenere molte cose, inclusi altri elementi p. Vogliamo trovare gli elementi p che sono figli del ref, non gli elementi p che sono figli degli altri elementi p.

Potreste pensare che potremmo semplicemente usare getElementsByTagName per questo, ma non possiamo. getElementsByTagName ricerca ricorsivamente e ritorna una singola lista per tutti gli elementi che trova. Dato che gli elementi p possono contenere altri elementi p, non possiamo usare getElementsByTagName, visto che ritornerebbe elementi p annidati che non vogliamo. Per trovare unicamente elementi figli diretti, dobbiamo farlo da soli.

Esempio 6.39. Trovare elementi figli diretti

    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 Come abbiamo visto nell'Esempio 6.9, “Ottenere i nodi figli”, l'attributo childNodes ritorna una lista di tutti i nodi figli di un elemento.
2 Comunque, abbiamo visto nell'Esempio 6.11, “I nodi figli possono essere di testo” che la lista ritornata da childNodes contiene tutti i differenti tipi di nodi, inclusi i nodi di testo. Non è quello che stiamo cercando, noi vogliamo unicamente i figli che sono elementi.
3 Ogni nodo ha un attributo nodeType, che può essere ELEMENT_NODE, TEXT_NODE, COMMENT_NODE, od ogni numero di altri valori. La lista completa di possibili valori è nel file __init__.py del package xml.dom. Leggete la sezione Package di questo capitolo per ulteriori informazioni sui package. Ma noi siamo interessati ai nodi che sono elementi, così possiamo filtrare la lista per includere unicamente quei nodi il cui nodeType è ELEMENT_NODE.
4 Una volta che abbiamo una lista di elementi reali, scegliendone uno casuale è facile. Python contiene un modulo chiamato random che include alcune utili funzioni. La funzione random.choice prende una lista di qualsiasi numero di oggetti e ritorna un oggetto random. In questo caso la lista contiene elementi p, così chosen è adesso un elemento p selezionato casualmente dai figli dell'elemento ref che abbiato fornito.