Использование lxml для извлечения данных, где все элементы не известны заранее - PullRequest
1 голос
/ 17 ноября 2010

У меня есть несколько файлов sgml, которые примерно стандартизированы.Тем не менее, могут быть данные, содержащиеся в теге, который я не знаю, существует, прежде чем я открою файл и лично прочитал его.Например, файлы имеют адреса, и обычно адреса имеют улицу, город, штат, почтовый индекс и телефон.Каждый элемент адреса обозначен тегом

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

Но, например, я обнаружил, что есть теги для страны, STREET1, STREET2.У меня есть более 200K файлов для обработки, и я хочу знать, возможно ли извлечь все элементы адресов, не беспокоясь о том, чтобы знать о существовании неизвестных тегов.

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

но то, что я получаю, проблематично, потому что я не могу определить, где заканчивается один элемент и начинается следующий

One Main StreetGotham City99999 0123555-123-5467

1 Ответ

2 голосов
/ 17 ноября 2010

Чтобы получить все теги, мы просматриваем документ следующим образом:

Предположим, что ваша структура XML выглядит следующим образом:

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

Мы анализируем ее:

>>> 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

Теперь предположим, что в вашем XML также есть дополнительные теги;теги, о которых вы не знаете.Поскольку мы выполняем итерацию по XML, приведенный выше код также возвращает эти теги.

<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>

Вышеприведенный код возвращает:

ADDRESS
STREET
STREET1
CITY
ZIP
PHONE
COUNTRY

Теперь, если мы хотим получить тексттеги, процедура такая же.Просто напечатайте tag.text так:

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

One Main Street
One Second Street
Gotham City
99999 0123
555-123-5467
USA
...