Como analisar arquivos XML usando python?

Como analisar arquivos XML usando python?

Desde encomendar mantimentos através do Instamart e compras de guarda-roupa em Myntra até reservar férias no MakemyTrip, os sites se tornaram indispensáveis ​​nesta década! Você já se perguntou como esses sites exibem informações para os clientes de maneira fácil de interpretar e também processam e interagem com os dados no back-end?

Existem certos formatos de arquivo que preenchem essa lacuna, sendo interpretáveis ​​tanto para linguagem de máquina quanto para humanos. Um desses formatos amplamente usados ​​é o XML, que significa Extensible Markup Language.

O que são arquivos XML e como os usamos?

Os arquivos XML são usados ​​para armazenar e transportar dados entre clientes e servidores. Ele nos permite definir os dados em um formato estruturado por meio de tags, atributos e valores. Uma das principais vantagens do XML é sua flexibilidade. Ele pode ser usado para representar dados em vários formatos e facilmente adaptado para novos usos. Isso o torna uma escolha popular para aplicativos como serviços da Web, troca de dados e arquivos de configuração. Neste artigo, mostrarei os diferentes métodos em python para analisar um arquivo XML com um exemplo prático.


Você está procurando automatizar a análise de XML? Experimente os fluxos de trabalho automatizados da Nanonets. Comece seu teste gratuito agora.


Compreendendo a estrutura dos arquivos XML

Antes de nos aprofundarmos nos detalhes de como analisar arquivos XML, vamos primeiro entender as diferentes partes de um documento XML. Em XML, um elemento é um bloco de construção fundamental de um documento que representa uma informação estruturada. O conteúdo do elemento deve ser colocado entre uma tag de abertura e uma tag de fechamento sempre conforme mostrado abaixo.

Harry Potter e a Pedra Filosofal

Usarei um arquivo de exemplo, “travel_pckgs.xml”, que contém detalhes dos diferentes pacotes turísticos oferecidos por uma empresa. Vou continuar a usar o mesmo arquivo em todo o blog para maior clareza.

<?xml version="1.0"?>
<travelPackages>
<package id='Paris vacation'>
<description>Experience the magnificent beauty of Paris and the french culture.</description>
<destination>Paris, France</destination>
<price>3000</price>
<duration>7</duration>
<payment>
<EMIoption>yes</EMIoption>
<refund>yes</refund>
</payment>
</package>
<package id='Hawaii Adventure'>
<description>Embark on an exciting adventure in Hawaii beaches!
</description>
<destination>Hawaii, USA</destination>
<price>4000</price>
<duration>10</duration>
<payment>
<EMIoption>no</EMIoption>
<refund>no</refund>
</payment>
</package>
<package id='Italian Getaway'>
<description>Indulge in the beauty and charm of Italy and get an all-
inclusive authentic Italian food tour!</description>
<destination>Italy</destination>
<price>2000</price>
<duration>8</duration>
<payment>
<EMIoption>yes</EMIoption>
<refund>no</refund>
</payment>
</package>
<package id='Andaman Island Retreat'>
<description>Experience the beauty of Island beaches,inclusive scuba
diving and Night kayaking through mangroves.</description>
<destination>Andaman and Nicobar Islands</destination>
<price>800</price>
<duration>8</duration>
<payment>
<EMIoption>no</EMIoption>
<refund>yes</refund>
</payment>
</package>
</travelPackages>

O arquivo contém dados de 4 pacotes turísticos, com detalhes de destino, descrição, preço e formas de pagamento fornecidos por uma agência. Vejamos o detalhamento das diferentes partes do XML acima:

  • Elemento Raiz: O elemento de nível superior é chamado de raiz, que é em nosso arquivo. Ele contém todos os outros elementos (vários passeios oferecidos)
  • Atributo: 'id' é o atributo de cada elemento em nosso arquivo. Observe que o atributo deve ter valores exclusivos ('Férias em Paris', 'Aventura no Havaí' etc.) para cada elemento. O atributo e seu valor geralmente são mencionados dentro da tag de início, como você pode ver.
  • Elementos filhos: Os elementos agrupados dentro da raiz são os elementos filhos. No nosso caso, todos os   tags são elementos filhos, cada um armazenando detalhes sobre um pacote turístico.
  • Subelementos: Um elemento filho pode ter mais subelementos dentro de sua estrutura. O elemento filho tem subelementos , , , e . A vantagem do XML é que ele permite armazenar informações hierárquicas por meio de vários elementos aninhados. O sub-elemento ainda tem sub-elementos e, que indicam se um determinado pacote tem opções de 'pagamento por EMI' e reembolso ou não.

Dica: Você pode criar uma exibição em árvore do arquivo XML para obter uma compreensão clara usando esta ferramenta. Confira a exibição em árvore hierárquica do nosso arquivo XML!

Como analisar arquivos XML usando python? Inteligência de dados PlatoBlockchain. Pesquisa vertical. Ai.

Ótimo! Queremos ler os dados armazenados nesses campos, pesquisar, atualizar e fazer alterações conforme necessário para o site, certo? Isso é chamado de análise, onde os dados XML são divididos em partes e diferentes partes são identificadas.

Existem várias maneiras de analisar um arquivo XML em python com diferentes bibliotecas. Vamos mergulhar no primeiro método!


Tente Nanonets para analisar arquivos XML. Comece sua avaliação gratuita sem nenhum dado de cartão de crédito.


Usando Mini DOM para analisar arquivos XML

Tenho certeza de que você deve ter encontrado o DOM (Document Object Model), uma API padrão para representar arquivos XML. Mini DOM é um módulo python embutido que implementa minimamente o DOM.  

Como funciona o mini DOM?

Ele carrega o arquivo XML de entrada na memória, criando uma estrutura semelhante a uma árvore “Árvore DOM” para armazenar elementos, atributos e conteúdo de texto. Como os arquivos XML também têm inerentemente uma estrutura de árvore hierárquica, esse método é conveniente para navegar e recuperar informações.

Vamos ver como importar o pacote com o código abaixo. Você pode analisar o arquivo XML usando xml.dom.minidom.parse() função e também obter o elemento raiz.

import xml.dom.minidom
# parse the XML file
xml_doc = xml.dom.minidom.parse('travel_pckgs.xml')
# get the root element
root = xml_doc.documentElement
print('Root is',root)

A saída que obtive para o código acima é:

>> Root is <DOM Element: travelPackages at 0x7f05824a0280>

Digamos que eu queira imprimir o local, a duração e o preço de cada pacote.  

A getAttribute () A função pode ser usada para recuperar o valor de um atributo de um elemento.

Se você deseja acessar todos os elementos em uma tag específica, use o getElementsByTagName ()  método e forneça a tag como entrada. A melhor parte é que getElementsByTagName() pode ser usado recursivamente para extrair elementos aninhados.

# get all the package elements
packages = xml_doc.getElementsByTagName('package')
# loop through the packages and extract the data
for package in packages:
package_id = package.getAttribute('id')
description = package.getElementsByTagName('description')[0].childNodes[0].data
price = package.getElementsByTagName('price')[0].childNodes[0].data
duration = package.getElementsByTagName('duration')[0].childNodes[0].data
print('Package ID:', package_id)
print('Description:', description)
print('Price:', price)

A saída do código acima é mostrada aqui, com o ID, o texto da descrição e os valores de preço de cada pacote extraídos e impressos.

Package ID: Paris vacation
Description: Experience the magnificent beauty of Paris and the french culture.
Price: 3000
Package ID: Hawaii Adventure
Description: Embark on an exciting adventure in Hawaii beaches!
Price: 4000
Package ID: Italian Getaway
Description: Indulge in the beauty and charm of Italy and get an all-inclusive authentic Italian food tour!
Price: 2000
Package ID: Andaman Island Retreat
Description: Experience the beauty of Island beaches,inclusive scuba
diving and Night kayaking through mangroves.
Price: 800

O analisador minidom também nos permite percorrer a árvore DOM de um elemento para seu elemento pai, seu primeiro elemento filho, último filho e assim por diante. Você pode acessar o primeiro filho do elemento usando o primeiro filho atributo. O nome e o valor do nó do elemento filho extraído também podem ser impressos por meio nome do nó e valor do nó atributos mostrados abaixo.

# get the first package element
paris_package = xml_doc.getElementsByTagName('package')[0]
# get the first child of the package element
first_child = paris_package.firstChild
#print(first_child)
>>
<DOM Element: description at 0x7f2e4800d9d0>
Node Name: description
Node Value: None

Você pode verificar que 'descrição' é o primeiro elemento filho de . Há também um atributo chamado filhosNodes que retornará todos os elementos filho presentes dentro do nó atual. Verifique o exemplo abaixo e sua saída.

child_elements=paris_package.childNodes
print(child_elements)
>>
[<DOM Element: description at 0x7f057938e940>, <DOM Element: destination at 0x7f057938e9d0>, <DOM Element: price at 0x7f057938ea60>, <DOM Element: duration at 0x7f057938eaf0>, <DOM Element: payment at 0x7f057938eb80>]

Semelhante a isso, minidom fornece mais maneiras de percorrer como parentNode, lastChild nextSibling, etc. Você pode verificar todas as funções disponíveis da biblioteca SUA PARTICIPAÇÃO FAZ A DIFERENÇA.

Porém, uma grande desvantagem desse método é o uso caro de memória, pois o arquivo inteiro é carregado na memória. É impraticável usar minidom para arquivos grandes. 


Automatize Nanonets de análise de XML. Comece sua avaliação gratuita hoje. Não é necessário cartão de crédito.


Usando a biblioteca ElementTree para analisar arquivos XML

ElementTree é um analisador python embutido amplamente usado que fornece muitas funções para ler, manipular e modificar arquivos XML. Este analisador cria uma estrutura semelhante a uma árvore para armazenar os dados em um formato hierárquico.

Vamos começar importando a biblioteca e chamando a função parse() do nosso arquivo XML. Você também pode fornecer o arquivo de entrada em um formato de string e usar o destring() função. Após inicializarmos uma árvore analisada, podemos usar obter root () função para recuperar a tag raiz, conforme mostrado abaixo.

import xml.etree.ElementTree as ET
tree = ET.parse('travel_pckgs.xml')
#calling the root element
root = tree.getroot()
print("Root is",root)
Output:
>>
Root is <Element 'travelPackages' at 0x7f93531eaa40>

A tag raiz 'travelPackages' foi extraída!

Digamos que agora queremos Acesso todo o primeiras tags filhas da raiz. Podemos usar um loop for simples e iterar sobre ele, imprimindo as tags filhas como destino, preço, etc. Observe que se tivéssemos especificado um valor de atributo dentro da tag de abertura da descrição, os parênteses não estariam vazios. Confira o trecho abaixo!

for x in root[0]:
print(x.tag, x.attrib)
Output:
>>
description {}
destination {}
price {}
duration {}
payment {}

Alternativamente, o iter () função pode ajudá-lo a encontrar qualquer elemento de interesse em toda a árvore. Vamos usar isso para extrair as descrições de cada pacote turístico em nosso arquivo. Lembre-se de usar o 'texto' para extrair o texto de um elemento.

For x in root.iter('description'):
print(x.text)
Output:
>> "Experience the magnificent beauty of Paris and the french culture." "Embark on an exciting adventure in Hawaii beaches!" "Indulge in the beauty and charm of Italy and get an all-inclusive authentic Italian food tour!" "Experience the beauty of Island beaches,inclusive scuba diving and Night kayaking through mangroves.

Ao usar o ElementTree, o loop for básico é bastante poderoso para acessar os elementos filhos. Vamos ver como.

Analisando arquivos XML com um loop for

Você pode simplesmente iterar pelos elementos filho com um loop for, extraindo os atributos conforme mostrado abaixo.

for tour in root:
print(tour.attrib)
Output:
>>
{'id': 'Paris vacation'}
{'id': 'Hawaii Adventure'}
{'id': 'Italian Getaway'}
{'id': 'Andaman Island Retreat'}

Para lidar com consultas e filtragem complexas, a ElementTee tem o encontrar tudo() método. Este método permite acessar todos os elementos filhos do tag passados ​​como parâmetros. Digamos que você queira conhecer os pacotes turísticos abaixo de $ 4000 e também ter a opção EMI como 'sim'. Confira o trecho.

for package in root.findall('package'):
price = int(package.find('price').text)
refund = package.find('payment/refund').text.strip("'")
if price < 4000 and refund == 'yes':
print(package.attrib['id'])

Basicamente, iteramos os pacotes por meio de root.findall('package') e extraímos o preço e o reembolso com achar() método. Depois disso, verificamos as restrições e filtramos os pacotes qualificados que são impressos abaixo.

Saída:

>>

férias em paris

Retiro da Ilha de Andaman

Usando o ElementTree, você pode facilmente modificar e atualizar os elementos e valores do arquivo XML, ao contrário do miniDOM e do SAX. Vamos verificar como na próxima seção.

Como modificar arquivos XML com ElementTree?

Digamos que é época de férias de Natal e a agência quer dobrar os custos do pacote. ElementTree fornece um conjunto() função, que podemos usar para atualizar os valores dos elementos. No código abaixo, acessei o preço de cada pacote através da função iter() e manipulei os preços. Você pode usar a função write() para gravar um novo arquivo XML com elementos atualizados.

for price in root.iter('price'):
new_price = int(price.text)*2
price.text = str(new_price)
price.set('updated', 'yes')
tree.write('christmas_packages.xml')

Você deve conseguir encontrar um arquivo de saída como o da imagem abaixo. Se você se lembra, os preços para Paris Vacation e Hawaii Adventure são $ 3000 e $ 4000 no arquivo original.

Como analisar arquivos XML usando python? Inteligência de dados PlatoBlockchain. Pesquisa vertical. Ai.

Mas, e se quisermos adicionar uma nova tag ao pacote Andaman para denotar que a estadia oferecida é 'Vila privada Premium'. O SubElemento() função de ElementTree nos permite adicionar novas subtags conforme a necessidade, conforme demonstrado no trecho abaixo. Você deve passar o elemento que deseja modificar e o novo tag como parâmetros para a função.

ET.SubElement(root[3], 'stay')
for x in root.iter('stay'):
resort = 'Premium Private Villa'
x.text = str(resort)
Como analisar arquivos XML usando python? Inteligência de dados PlatoBlockchain. Pesquisa vertical. Ai.

Espero que você tenha obtido os resultados também! O pacote também oferece pop () função, através da qual você pode excluir atributos e subelementos se forem desnecessários.


API simples para XML (SAX)

SAX é outro analisador python, que supera a deficiência do miniDOM lendo o documento sequencialmente. Ele não carrega a árvore inteira em sua memória e também permite descartar itens, reduzindo o uso de memória.

Primeiro, vamos criar um objeto analisador SAX e registrar funções de retorno de chamada para os diferentes eventos que você deseja manipular no documento XML. Para fazer isso, defino uma classe TravelPackageHandler personalizada, conforme mostrado abaixo, subclassificando o ContentHandler do SAX.

import xml.sax
# Define a custom SAX ContentHandler class to handle events
class TravelPackageHandler(xml.sax.ContentHandler):
def __init__(self):
self.packages = []
self.current_package = {}
self.current_element = ""
self.current_payment = {} def startElement(self, name, attrs):
self.current_element = name
if name == "package":
self.current_package = {"id": attrs.getValue("id")} def characters(self, content):
if self.current_element in ["description", "destination", "price", "duration", "EMIoption", "refund"]:
self.current_package[self.current_element] = content.strip()
if self.current_element == "payment":
self.current_payment = {} def endElement(self, name):
if name == "package":
self.current_package["payment"] = self.current_payment
self.packages.append(self.current_package)
if name == "payment":
self.current_package["payment"] = self.current_payment def startElementNS(self, name, qname, attrs):
pass def endElementNS(self, name, qname):
pass

No trecho acima, o startElement(), caracteres(), e elemento final() métodos são usados ​​para extrair os dados dos elementos e atributos XML. À medida que o analisador SAX lê o documento, ele aciona as funções de retorno de chamada registradas para cada evento que encontra. Por exemplo, se encontrar o início de um novo elemento, chama a função startElement(). Agora, vamos usar nosso manipulador personalizado para obter os vários IDs de pacote analisando nosso arquivo XML de exemplo.

# Create a SAX parser object
parser = xml.sax.make_parser()
handler = TravelPackageHandler()
parser.setContentHandler(handler)
parser.parse("travel_pckgs.xml")
for package in handler.packages:
print(f'Package: {package["id"]}')

Saída >>

Pacote: Férias em Paris

Pacote: Aventura no Havaí

Pacote: Escapadela à Itália

Pacote: Retiro na Ilha de Andaman

O SAX pode ser usado para arquivos grandes e streaming devido à sua eficiência. Mas é inconveniente ao trabalhar com elementos profundamente aninhados. E se você quiser acessar qualquer nó de árvore aleatória? Como não suporta acesso aleatório, o parser terá que ler todo o documento sequencialmente para acessar um elemento específico.


Sincronize todas as suas entradas duplas com Nanonets. Mantenha todas as suas contas equilibradas, 24×7. Configure seus processos contábeis em <15 minutos. Veja como.


Analisador de pull de streaming para XML

Este é o pulldom Biblioteca Python que fornece uma API de analisador pull de streaming com uma interface semelhante a DOM.

Como funciona o Tech & Data Studio:

Ele processa os dados XML de maneira “puxada”. Ou seja, você solicita explicitamente ao analisador para fornecer o próximo evento (por exemplo, elemento inicial, elemento final, texto etc.) nos dados XML.

A sintaxe é familiar ao que vimos nas bibliotecas anteriores. No código abaixo, demonstro como importar a biblioteca e utilizá-la para imprimir os tours com duração igual ou superior a 4 dias, e também fazer o reembolso no caso de cancelamento.

from xml.dom.pulldom import parse
events = parse("travel_pckgs.xml")
for event, node in events:
if event == pulldom.START_ELEMENT and node.tagName == 'package':
duration = int(node.getElementsByTagName('duration')[0].firstChild.data)
refund = node.getElementsByTagName('refund')[0].firstChild.data.strip("'")
if duration > 4 and refund == 'yes':
print(f"Package: {node.getAttribute('id')}")
print(f"Duration: {duration}")
print(f"Refund: {refund}")

Você deve obter uma saída como:

Pacote: Férias em Paris

Duração: 7

Reembolso: sim

Pacote: Retiro na Ilha de Andaman

Duração: 8

Reembolso: sim

Confira os resultados! O analisador pull combina alguns recursos do miniDOM e do SAX, tornando-o relativamente eficiente.

Resumo

Tenho certeza de que você já tem uma boa compreensão dos vários analisadores disponíveis em python. Saber quando escolher qual analisador economizar tempo e recursos é igualmente importante. Entre todos os parsers que vimos, o ElementTree oferece compatibilidade máxima com expressões XPath que ajudam a realizar consultas complexas. O Minidom tem uma interface fácil de usar e pode ser escolhido para lidar com arquivos pequenos, mas é muito lento no caso de arquivos grandes. Ao mesmo tempo, o SAX é usado em situações em que o arquivo XML é constantemente atualizado, como no caso do aprendizado de máquina em tempo real.

Uma alternativa para analisar seus arquivos é usar ferramentas de análise automática como Nanonets. Nanonets podem ajudá-lo a extrair dados de qualquer tipo de documento em segundos, sem escrever uma única linha de código.

Ootimize o desempenho do seu negócio, economize custos e impulsione o crescimento. Descobrir como os casos de uso das Nanonets podem ser aplicados ao seu produto.


Carimbo de hora:

Mais de IA e aprendizado de máquina