Работа с XML из Python
Не все элементы входных данных XML будут в конечном итоге являться элементами анализируемого дерева. В настоящий момент этот модуль пропускает все комментарии XML, инструкции по обработке и объявления типа документа во входных данных. Тем не менее, деревья, построенные с использованием API этого модуля, а не синтаксического анализа из XML-текста, могут иметь комментарии и инструкции по обработке в них.
Создание и сборка XML-документов
Импорт модуля Элемента Дерева
import xml.etree.ElementTree as ET
Функция Element () используется для создания элементов XML
p=ET.Element('parent')
Функция SubElement (), используемая для создания вложенных элементов в элементе give
c = ET.SubElement(p, 'child1')
Функция dump() используется для вывода элементов xml .
ET.dump(p) #
Если вы хотите сохранить в файл, создайте дерево XML с функцией ElementTree() и сохраните в файл, используя метод write()
tree = ET.ElementTree(p) tree.write("sample.xml")
Функция Comment() используется для вставки комментариев в XML-файл.
comment = ET.Comment('user comment') p.append(comment) #этот комментарий будет добавлен к родительскому элементу ET.dump(p) #
Изменение файла XML
Импортируйте модуль ElementTree и откройте файл XML, получите элемент XML
import xml.etree.ElementTree as ET tree = ET.parse('sample.xml') root=tree.getroot() element = root[0] #получите первого ребенка родительского корня element #
Элементом объекта можно управлять, изменяя его поля, добавляя и изменяя атрибуты, добавляя и удаляя дочерние элементы
element.set('attribute_name', 'attribute_value') #установите артрибут xml элементу element.text="string_text"
Если вы хотите удалить элемент, используйте метод Element.remove()
root.remove(element)
Метод ElementTree.write() , используемый для вывода объекта XML в файлы XML.
tree.write('sample.xml')
Открытие и чтение больших файлов XML с помощью iterparse (инкрементальный анализ)
Иногда мы не хотим загружать весь XML-файл, чтобы получить необходимую нам информацию. В этих случаях полезно постепенно загружать соответствующие разделы и затем удалять их, когда мы закончим. С помощью функции iterparse вы можете редактировать дерево элементов, которое хранится при разборе XML.
Импортируйте объект ElementTree:
import xml.etree.ElementTree as ET
Откройте файл .xml и переберите все элементы:
for event, elem in ET.iterparse("yourXMLfile.xml"): # . сделайте что-нибудь .
Кроме того, мы можем искать только определенные события, такие как начальный / конечный теги или пространства имен. Если эта опция не указана (как указано выше), возвращаются только события «end»:
events=("start", "end", "start-ns", "end-ns") for event, elem in ET.iterparse("yourXMLfile.xml", events=events): # . сделайте что-нибудь .
Вот полный пример, показывающий, как очистить элементы из дерева в памяти, когда мы закончим с ними:
for event, elem in ET.iterparse("yourXMLfile.xml", events=("start","end")): if elem.tag == "record_tag" and event == "end": print elem.text elem.clear() # . сделайтe что-нибудь другое .
Открытие и чтение с помощью ElementTree
Импортируйте объект ElementTree, откройте соответствующий XML-файл и получите корневой тег:
import xml.etree.ElementTree as ET tree = ET.parse("yourXMLfile.xml") root = tree.getroot()
Есть несколько способов поиска по дереву. Сначала по итерации:
for child in root: print(child.tag, child.attrib)
В противном случае вы можете ссылаться на определенные места, такие как список:
print(root[0][1].text)
Для поиска конкретных тегов по имени, используйте .find или .findall :
print(root.findall("myTag")) print(root[0].find("myOtherTag"))
Поиск в XML с помощью XPath
Начиная с версии 2.7 ElementTree имеет лучшую поддержку XPath запросов. XPath — это синтаксис, позволяющий вам перемещаться по XML, как SQL используется для поиска в базе данных. Как find и findall функции поддержки XPath. Xml ниже будет использоваться для этого примера
Мечтают ли андроиды об электроовцах? Philip K. Dick The Colour of Magic Terry Pratchett The Eye of The World Robert Jordan
Поиск всех книг:
import xml.etree.cElementTree as ET tree = ET.parse('sample.xml') tree.findall('Books/Book')
Поиск книги с названием «Цвет магии»:
tree.find("Books/Book[Title='The Colour of Magic']") # всегда используйте '' в правой стороне сравнения
tree.find("Books/Book[@id='5']") # поиск с xml атрибутами должен иметь '@' перед именем
Поиск второй книги:
tree.find("Books/Book[2]") # индексы начинаются с 1, не с 0
Поиск последней книги:
tree.find("Books/Book[last()]") # 'last' единственная xpath функция позволенная в ElementTree
Поиск всех авторов:
tree.findall(".//Author") # поиск с // должен использовать родственный путь
Обработка XML-файлов Python
XML означает расширяемый язык разметки . Стандарт XML — это гибкий способ создания информационных форматов и электронного обмена структурированными данными через общедоступный Интернет, а также через корпоративные сети.
XML Parser
Объектная модель документа (DOM) , определяет стандарт для доступа и работы с документами. XML DOM определяет стандартный способ для доступа и манипулирования XML — документов. Он представляет XML-документ как древовидную структуру.
Разбор XML в Python
Python может анализировать XML-документы несколькими способами. В нем есть традиционные парсеры dom и sax. В этой главе основное внимание будет уделено использованию встроенного XML- модуля в python для синтаксического анализа XML.
Пример XML-документа
import xml.etree.ElementTree doc = xml.etree.ElementTree.parse('data.xml').getroot() for elem in doc.findall('items/item'): print (elem.get('name'))
product1 product2 product3 product4 product5
Минимальная реализация DOM (xml.dom.minidom)
Пример DOM
Xml.dom.minidom минимальная реализация интерфейса объектной модели документа, с API , аналогичной на других языках. Он должен быть проще, чем полный DOM, а также значительно меньше. Программисты, которые еще не владеют DOM, должны вместо этого использовать модуль xml.etree.ElementTree для своей обработки XML.
from xml.dom import minidom xmldoc = minidom.parse('data.xml') product_list = xmldoc.getElementsByTagName('item') print("No of Items : ", len(product_list)) for product in product_list: print(product.attributes['name'].value)
No of Items : 5 product1 product2 product3 product4 product5
Открыть xml-файлы в python с плохим представлением
У меня 100 файлов формата xml, которые я не могу открыть Пример файла:
%skipzero[1,2]%
Я использую xml.etree.ElementTree для парсинга файла
import xml.etree.ElementTree as ET tree = ET.parse('pathname.xml') root = tree.getroot() for child in root.iter('count'): print(child.tag, child.attrib)
Ошибка связана с «not well-formed» Я знаю причину ошибки (In the beginning, you need to delete ‘
Как я учился работать с XML
Работая с xml в питоне многие пользуются довольно удобным встроенным модулем xml.dom.minidom. Вся информация в нем, включая содержимое тегов, представляется как эдакие ноды, работа с которыми ведется напрямую. Вот кусок кода обработки xml-файла:
- app_xml = xmlp.parse( «base.xml» )
- id = app_xml.createElement(att)
- node = app_xml.createTextNode(«simple.App»)
- id.appendChild(node)
- root.appendChild(id)
- res = open( «base.xml» , «w» )
- res.writelines(app_xml.toprettyxml())
- res.close()
Весь этот код, как несложно догадаться, открывает существующий xml-файл, парсит и добавляет к нему один-единственный тег id со строкой «simple.App». Громоздко? Да не то слово. Мало того, обнаружился еще один неприятный баг — со времен Python 2.4 функция toprettyxml(), предназначенная для выдачи содержимого ноды или дерева нод в текстовом виде, зачем-то добавляет к каждой строчке символ перевода каретки, в результате чего вместо
На первый взгляд, это не критично, поскольку значение остается нетронутым, однако в некоторых случаях и для некоторых парсеров (если, например, собираетесь использовать сгенеренный XML в других разработках) — при обработке числовых данных будет выводиться ошибка. В частности, этим грешит сборщик Adobe AIR-приложений, биндинги к которому я, собственно, и писал.
Поиски в интернете дали результат. Получалось, что либо я должен использовать в своем коде хак в виде лишней функции строчек эдак на двадцать, либо использовать стандартный toxml(), который хоть и генерит валидные файлы — но всю инфу в них располагает в одну строчку, то есть весь мой дескриптор превратился в кашу вида
Назовите меня эстетом, но при больших объемах файла (да еще и с комментариями) искать в подобной куче ошибочные значения — то еще удовольствие.
И тогда я стал искать альтернативный вариант.
Свет в конце тоннеля
И этот вариант пришел в виде модуля lxml. Он упоминался как раз в теме, в которой ругали xml.dom.minidom за творимое им безобразие 🙂
А теперь давайте взглянем на код генерации хэндла приложения без всяких добавлений и переписываний:
- root = etree.Element( «initialWindow» )
- etree.SubElement(root, «title» ).text = title
- etree.SubElement(root, «content» ).text = content
- etree.SubElement(root, «height» ).text = str(height)
- etree.SubElement(root, «width» ).text = str(width)
- app_window = etree.tostring(root)
- .
- root = etree.Element( «application» , xmlns= «http://ns.adobe.com/air/application/1.5» )
- etree.SubElement(root, «id» ).text = id
- etree.SubElement(root, «version» ).text = version
- etree.SubElement(root, «filename» ).text = filename
- etree.SubElement(root, «name» ).text = self.name
- root.append(etree.XML(app_window))
- handle = etree.tostring(root, pretty_print=True, encoding= ‘utf-8’ , xml_declaration=True)
- applic = open(self.fullpath+ «/» +self.name+ «-app.xml» , «w» )
- applic.writelines(handle)
- applic.close()
Куда понятнее и нагляднее, не находите? Этот код позволяет сгенерировать вот такой чистенький и красивенький XML:
Думаю, 90% кода в объяснении не нуждаются. Вся уличная магия заключена в строчке handle = etree.tostring(root, pretty_print=True, encoding=’utf-8′, xml_declaration=True). Здесь pretty_print — замена того самого злосчастного toprettyxml(), только, в отличие от него, работающая нормально. Также мы задаем кодировку и приделываем стандартную строку заголовка XML-документа.
По утверждениям, этот модуль, как ни странно, работает раза в два быстрее, чем стандартный. Устанавливается он элементарно через setuptools:
$ sudo easy_install lxml
Нормальный туториал лежит на официальном сайте, вот прямая ссылка.
Да здравствует красивый, удобный и валидный код! Удачи вам всем, пишите комментарии.
