Разбор чистых XML-тегов с LXML и Python

При анализе XML-документов в формате:

<Car> <Color>Blue</Color> <Make>Chevy</Make> <Model>Camaro</Model> </Car> 

Я использую следующий код:

  • Код Python для удаления тегов HTML из строки
  • Получение международных символов с веб-страницы?
  • Операция строки Python, извлечение текста между html-тегами
  • Посещение узлов в дереве синтаксиса с помощью модуля Python ast
  • Каковы операционные методы для булевых 'и', 'или' в Python?
  • Декларация XML standalone = "yes" lxml
  •  carData = element.xpath('//Root/Foo/Bar/Car/node()[text()]') parsedCarData = [{field.tag: field.text for field in carData} for action in carData] print parsedCarData[0]['Color'] #Blue 

    Этот код не будет работать, если тег пуст, например:

     <Car> <Color>Blue</Color> <Make>Chevy</Make> <Model/> </Car> 

    Используя тот же код, что и выше:

     carData = element.xpath('//Root/Foo/Bar/Car/node()[text()]') parsedCarData = [{field.tag: field.text for field in carData} for action in carData] print parsedCarData[0]['Model'] #Key Error 

    Как бы я разобрал этот пустой тег.

  • Подавлять вывод из подпроцесса.
  • Почему моя функция возвращает None?
  • gnuplot против Matplotlib
  • Возможно ли заблокировать файл sqlite в файловой системе NFS?
  • Python: загрузка файла через FTP-сервер
  • Регулярное выражение Python findall *
  • 4 Solutions collect form web for “Разбор чистых XML-тегов с LXML и Python”

    Вы помещаете фильтр [text()] который явно запрашивает только те элементы, у которых есть текстовые узлы … и тогда вы недовольны, когда не дают вам элементов без текстовых узлов?

    Оставьте этот фильтр, и вы получите элемент модели:

     >>> s=''' ... <root> ... <Car> ... <Color>Blue</Color> ... <Make>Chevy</Make> ... <Model/> ... </Car> ... </root>''' >>> e = lxml.etree.fromstring(s) >>> carData = e.xpath('Car/node()') >>> carData [<Element Color at 0x23a5460>, <Element Make at 0x23a54b0>, <Element Model at 0x23a5500>] >>> dict(((e.tag, e.text) for e in carData)) {'Color': 'Blue', 'Make': 'Chevy', 'Model': None} 

    Тем не менее, если ваша ближайшая цель состоит в том, чтобы перебирать узлы в дереве, вы можете вместо этого использовать lxml.etree.iterparse() , что позволит избежать попыток построить полное DOM-дерево в памяти и в противном случае будет намного более эффективным, чем создавая дерево, а затем перебираем его с помощью XPath. (Думайте SAX, но без сумасшедшего и болезненного API).

    Реализация с помощью iterparse может выглядеть так:

     def get_cars(infile): in_car = False current_car = {} for (event, element) in lxml.etree.iterparse(infile, events=('start', 'end')): if event == 'start': if element.tag == 'Car': in_car = True current_car = {} continue if not in_car: continue if element.tag == 'Car': yield current_car continue current_car[element.tag] = element.text for car in get_cars(infile = cStringIO.StringIO('''<root><Car><Color>Blue</Color><Make>Chevy</Make><Model/></Car></root>''')): print car 

    … это больше кода, но (если бы мы не использовали StringIO для примера), он мог обрабатывать файл, который намного больше, чем мог бы поместиться в память.

    Я не знаю, есть ли лучшее решение, встроенное в lxml, но вы можете просто использовать .get() :

     print parsedCarData[0].get('Model', '') 

    Я поймаю исключение:

     try: print parsedCarData[0]['Model'] except KeyError: print 'No model specified' 

    Исключения в Python не являются исключительными в том же смысле, что и на других языках, где они более строго связаны с условиями ошибки. Вместо этого они часто являются частью обычного использования модулей, по дизайну. Итератор поднимает StopIteration чтобы сигнализировать, что он, например, достиг конца итерации.

    Edit: Если вы уверены, что только этот элемент может быть пустым @CharlesDuffy имеет это право в том, что использование get() , вероятно, лучше. Но в целом я бы предпочел использовать исключения, чтобы легко обрабатывать разнообразные исключительные результаты.

    Решение: используйте блок try/except чтобы поймать ключевую ошибку.

    Python - лучший язык программирования в мире.