En utilisant lxml pour extraire les données où tous les éléments ne sont pas connus à l'avance

StackOverflow https://stackoverflow.com/questions/4201562

  •  25-09-2019
  •  | 
  •  

Question

J'ai quelques fichiers SGML qui sont à peu près normalisés. Cependant, il peut y avoir des données contenues dans une étiquette que je ne sais pas existe avant d'ouvrir le fichier et lu personnellement. Par exemple, les fichiers ont des adresses et généralement les adresses ont une rue, une ville, un état, un zip et un téléphone. Chaque élément de l'adresse est indiquée par une balise

 <ADDRESS>
 <STREET>One Main Street
 <CITY>Gotham City
 <ZIP>99999 0123
 <PHONE>555-123-5467
 </ADDRESS>

Mais, par exemple, je l'ai découvert qu'il ya des balises pour Country, STREET1, STREET2. J'ai plus de 200K fichiers à traiter et je veux savoir s'il est possible de retirer tous les éléments des adresses sans avoir à se soucier de savoir l'existence de balises inconnues.

Ce que je l'ai fait jusqu'à présent est

h=fromstring(my_data_in_a_string)
for each in h.cssselect('mail_address'):
    each.text_content()

mais ce que je reçois est problématique parce que je ne peux pas identifier où un élément se termine et la suivante commence

One Main StreetGotham City99999 0123555-123-5467
Était-ce utile?

La solution

Pour obtenir toutes les balises, nous iter à travers le document comme celui-ci:

Supposons que votre structure XML est comme ceci:

<ADDRESS>
 <STREET>One Main Street</STREET>
 <CITY>Gotham City</CITY>
 <ZIP>99999 0123</ZIP>
 <PHONE>555-123-5467</PHONE>
 </ADDRESS>

l'analyse syntaxique:

>>> from lxml import etree
>>> f = etree.parse('foo.xml')  # path to XML file
>>> root = f.getroot() # get the root element
>>> for tags in root.iter(): # iter through the root element
...     print tags.tag       # print all the tags
... 
ADDRESS
STREET
CITY
ZIP
PHONE

Maintenant, supposons que votre XML possède des balises supplémentaires ainsi; étiquettes vous n'êtes pas au courant au sujet. Puisque nous sommes à travers le XML itérer, le code ci-dessus renvoie ces balises ainsi.

<ADDRESS>
         <STREET>One Main Street</STREET>
         <STREET1>One Second Street</STREET1>
        <CITY>Gotham City</CITY>
         <ZIP>99999 0123</ZIP>
         <PHONE>555-123-5467</PHONE>         
         <COUNTRY>USA</COUNTRY>    
</ADDRESS>

Le code ci-dessus retourne:

ADDRESS
STREET
STREET1
CITY
ZIP
PHONE
COUNTRY

Maintenant, si nous voulons obtenir le texte des balises, la procédure est la même. Il suffit d'imprimer tag.text comme ceci:

>>> for tags in root.iter():
...     print tags.text
... 

One Main Street
One Second Street
Gotham City
99999 0123
555-123-5467
USA
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top