[Python] Parser XML нужна помощь.

Intheomsk

Создатель
Регистрация
1 Июл 2013
Сообщения
23
Реакции
3
Здравствуйте. Написал парсер для XML файла, но проблема в том, что если в одном из тегов пропущен атрибут - он вылетает. Как сделать проверку на наличие атрибута в тэге (если нет - записать значение none, например) ?
 

errogaht

Постоялец
Регистрация
15 Май 2013
Сообщения
50
Реакции
10
какой библиотекой пользуетесь для парсинга?
вообще если совершаемое действие не обязательно 100% выполнится то используется конструкция:
Код:
try:
    data = GetTag(text)
except:
    echo 'Unable to parse tag'
    data = ''
 

Intheomsk

Создатель
Регистрация
1 Июл 2013
Сообщения
23
Реакции
3
какой библиотекой пользуетесь для парсинга?
вообще если совершаемое действие не обязательно 100% выполнится то используется конструкция:
Код:
try:
    data = GetTag(text)
except:
    echo 'Unable to parse tag'
    data = ''


Пользовался xml.dom minidom.
Перешел на lxml etree - проблема с несуществующим значением решилась, тут результат none выходит какраз.

Сейчас проблема в другом: одна из частей xml файла:
Код:
<UL_ADDRESS DTSTART="28.02.2013" NAMEISPORG="Руководитель">
<VIDADR ID="1" NAME="Адрес исполнительного органа">
</VIDADR>
<ADDRESS INDEKS="644077" DOM="84" KVART="47">
<REGION ID="1100055" NAME="Омская обл" KOD_KL="55">
</REGION>
<GOROD ID="1102823" NAME="Омск г" KOD_KL="55000001000">
</GOROD>
<STREET ID="1560208" NAME="Мира пр-кт" KOD_ST="550000010000739">
</STREET>
</ADDRESS>
</UL_ADDRESS>
[/spoil]

Мне нужно отпарсеные данные записывать в файл, есть цикл

[spoil]
Код:
for node in tree.iterfind('.//UL_ADDRESS/ADDRESS'):
    print node.get('INDEKS'), node.get('DOM'), node.get('KVART')

Он отлично забирает значение нужных аттрибутов в ключе адрес, но как в этом же цикле забрать значения аттрибутов region, gorod, street ?

tree.xpath('.//UL_ADDRESS/ADDRESS/REGION')[0].get('NAME') - забирает только аттрибут с индексом [0], и не дает подставить в индекс 'node'
 

errogaht

Постоялец
Регистрация
15 Май 2013
Сообщения
50
Реакции
10
Там в lxml etree рядом с get который вы используете есть

getchildren(self)
Returns all direct children. The elements are returned in document order.
Может его попробовать?
выдаст детей этого тега.
result = node.getchildren
и потом по идее перебирать
result[0] - возможно будет REGION
result[2] - GOROD
?
 

Intheomsk

Создатель
Регистрация
1 Июл 2013
Сообщения
23
Реакции
3
Судя по документации:

getchildren()
Deprecated since version 2.7: Use list(elem) or iteration.

Если использовать list(node), то он находит нужые значения:

Код:
[<Element REGION at 0x2561fa8>, <Element GOROD at 0x2561288>, <Element STREET at 0x25612b0>]
[<Element REGION at 0x25612b0>, <Element GOROD at 0x25610a8>, <Element STREET at 0x2561490>]
[<Element REGION at 0x2561490>, <Element GOROD at 0x2561fa8>, <Element STREET at 0x2561a30>]
[<Element REGION at 0x2561490>, <Element GOROD at 0x2561a30>, <Element STREET at 0x25612b0>]

Как получить значение аттрибута?
 
Последнее редактирование:

errogaht

Постоялец
Регистрация
15 Май 2013
Сообщения
50
Реакции
10
Вы получили элементы, доступ к атрибуту элемента вот так:

Код:
# -*- coding: utf-8 -*-
import lxml.etree as etree

string = """
<UL_ADDRESS DTSTART="28.02.2013" NAMEISPORG="Руководитель">
<VIDADR ID="1" NAME="Адрес исполнительного органа">
</VIDADR>
<ADDRESS INDEKS="644077" DOM="84" KVART="47">
<REGION ID="1100055" NAME="Омская обл" KOD_KL="55">
</REGION>
<GOROD ID="1102823" NAME="Омск г" KOD_KL="55000001000">
</GOROD>
<STREET ID="1560208" NAME="Мира пр-кт" KOD_ST="550000010000739">
</STREET>
</ADDRESS>
</UL_ADDRESS>
"""
tree = etree.fromstring(string)
lol = tree.find('ADDRESS')
print lol
list_of_nodes = list(lol)
print list_of_nodes
for node in list_of_nodes:
    for name, value in node.items():
        print name, value
[/spoil]

на выходе получилось:

[spoil]
Код:
<Element ADDRESS at 0x232a8c8>
[<Element REGION at 0x232adc8>, <Element GOROD at 0x232a418>, <Element STREET at 0x232a468>]
ID 1100055
NAME Омская обл
KOD_KL 55
ID 1102823
NAME Омск г
KOD_KL 55000001000
ID 1560208
NAME Мира пр-кт
KOD_ST 550000010000739

Process finished with exit code 0

док Для просмотра ссылки Войди или Зарегистрируйся
 

Intheomsk

Создатель
Регистрация
1 Июл 2013
Сообщения
23
Реакции
3
Сделал немного по-другому, работает. Появилась еще проблема с кодировкой.

Некоторые аттрибуты присутствуют не во всех тэгах. Например есть запрос:

Код:
node.get('KORP')

Если значение есть - то должно быть
Код:
node.get('KORP').encode('UTF-8')
. а если значения нет, т.е. None, то так делать нельзя (Nontype не кодируется), то для None должно быть
Код:
str(node.get('KORP')).encode('UTF-8')
Есть мысли ? :)
 
Последнее редактирование:

errogaht

Постоялец
Регистрация
15 Май 2013
Сообщения
50
Реакции
10
Можно сделать такую проверку:

Код:
if node.get('KORP'):
    korp = node.get('OGRN').encode('UTF-8')
else:
    korp = ''
 

Intheomsk

Создатель
Регистрация
1 Июл 2013
Сообщения
23
Реакции
3
Не выходит. AttributeError: 'NoneType' object has no attribute 'encode'

ADD: Прошу прощения, аттрибуты в предыдущем сообщении одинаковые у всех. Поправил пост, вопрос актуален.
 
Последнее редактирование:

errogaht

Постоялец
Регистрация
15 Май 2013
Сообщения
50
Реакции
10
Можно попробовать так:

Код:
try:
    korp = node.get('OGRN').encode('UTF-8')
except:
    korp = ''
или попробовать сделать проверку на тип функцией type()
Код:
print type(node.get('OGRN'))

if type(node.get('OGRN')) == something:
    do something
 
Сверху