Eu tenho muitas linhas em um banco de dados que contém XML e estou tentando escrever um script Python para contar instâncias de um atributo de nó específico.
Minha árvore se parece com:
<foo>
<bar>
<type foobar="1"/>
<type foobar="2"/>
</bar>
</foo>
Como posso acessar os atributos "1"
e "2"
no XML usando Python?
Respostas:
Eu sugiro
ElementTree
. Existem outras implementações compatíveis da mesma API, comolxml
, ecElementTree
na própria biblioteca padrão do Python; mas, nesse contexto, o que eles adicionam principalmente é ainda mais velocidade - a facilidade da parte da programação depende da API, queElementTree
define.Primeiro, crie uma instância Element a
root
partir do XML, por exemplo, com a função XML ou analisando um arquivo com algo como:Ou qualquer uma das muitas outras maneiras mostradas em
ElementTree
. Então faça algo como:E padrões de código semelhantes, geralmente bastante simples.
fonte
lxml
adiciona mais do que velocidade. Ele fornece acesso fácil a informações como nó pai, número da linha na fonte XML, etc., que podem ser muito úteis em vários cenários.Warning The xml.etree.ElementTree module is not secure against maliciously constructed data. If you need to parse untrusted or unauthenticated data see XML vulnerabilities.
minidom
é o mais rápido e bastante direto.XML:
Pitão:
Resultado:
fonte
item
diretamente do nível superior do documento? não seria mais limpo se você fornecesse o caminho (data->items
)? porque, e se você também tivessedata->secondSetOfItems
esses nós nomeadositem
e desejasse listar apenas um dos dois conjuntos deitem
?Você pode usar o BeautifulSoup :
fonte
BeautifulStoneSoup
está DEPRECIADO. Basta usarBeautifulSoup(source_xml, features="xml")
ElementTree
, infelizmente ele não consegue analisar, a menos que eu ajuste a fonte em alguns locais, masBeautifulSoup
trabalhei imediatamente sem nenhuma alteração!Existem muitas opções por aí. O cElementTree parece excelente se a velocidade e o uso da memória forem um problema. Tem muito pouca sobrecarga em comparação com a simples leitura no arquivo usando
readlines
.As métricas relevantes podem ser encontradas na tabela abaixo, copiadas do site do cElementTree :
Como apontado pelo @jfs ,
cElementTree
vem com o Python:from xml.etree import cElementTree as ElementTree
.from xml.etree import ElementTree
(a versão C acelerada é usada automaticamente).fonte
from xml.etree import cElementTree as ElementTree
. Em Python 3:from xml.etree import ElementTree
(a versão acelerada C é usada automaticamente)ElementTree
para uma tarefa específica. Para documentos que cabem na memória, é muito mais fácil de usarminidom
e funciona bem para documentos XML menores.Sugiro xmltodict por simplicidade.
Ele analisa seu XML para um OrderedDict;
fonte
result["foo"]["bar"]["type"]
é uma lista de todos os<type>
elementos, por isso ainda está funcionando (mesmo que a estrutura seja talvez um pouco inesperada).O lxml.objectify é realmente simples.
Tomando seu texto de exemplo:
Resultado:
fonte
count
armazena as contagens de cada item em um dicionário com chaves padrão, para que você não precise verificar a associação. Você também pode tentar olharcollections.Counter
.Python tem uma interface para o analisador de XML expat.
É um analisador não validador, portanto, XML ruim não será capturado. Mas se você sabe que seu arquivo está correto, isso é muito bom, e você provavelmente obterá as informações exatas que deseja e poderá descartar o resto rapidamente.
fonte
Eu posso sugerir declxml .
Divulgação completa: escrevi esta biblioteca porque estava procurando uma maneira de converter entre estruturas de dados XML e Python sem precisar escrever dezenas de linhas de código de análise / serialização imperativo com o ElementTree.
Com declxml, você usa processadores para definir declarativamente a estrutura do seu documento XML e como mapear entre estruturas de dados XML e Python. Os processadores são usados para serialização e análise, bem como para um nível básico de validação.
A análise nas estruturas de dados Python é simples:
Qual produz a saída:
Você também pode usar o mesmo processador para serializar dados em XML
Que produz a seguinte saída
Se você deseja trabalhar com objetos em vez de dicionários, também pode definir processadores para transformar dados para e de objetos.
Que produz a seguinte saída
fonte
Apenas para adicionar outra possibilidade, você pode usar desembaraçar , pois é uma biblioteca simples de XML para Python. Aqui você tem um exemplo:
Instalação:
Uso:
Seu arquivo XML (um pouco alterado):
Acessando os atributos com
untangle
:A saída será:
Mais informações sobre desembaraçar podem ser encontradas em " desembaraçar ".
Além disso, se você estiver curioso, poderá encontrar uma lista de ferramentas para trabalhar com XML e Python em " Python e XML ". Você também verá que os mais comuns foram mencionados por respostas anteriores.
fonte
Aqui está um código muito simples, mas eficaz, usando
cElementTree
.Isso é do " python xml parse ".
fonte
XML:
Código Python:
Resultado:
fonte
Isso imprimirá o valor do
foobar
atributo.fonte
xml.etree.ElementTree vs. lxml
Estes são alguns profissionais das duas bibliotecas mais usadas que eu gostaria de conhecer antes de escolher entre elas.
xml.etree.ElementTree:
lxml
standalone="no"
?.node
.sourceline
permite obter facilmente a linha do elemento XML que você está usando.fonte
Acho o Python xml.dom e xml.dom.minidom bastante fácil. Lembre-se de que o DOM não é bom para grandes quantidades de XML, mas se sua entrada for bastante pequena, isso funcionará bem.
fonte
Não há necessidade de usar uma API específica da lib, se você usar
python-benedict
. Apenas inicialize uma nova instância do seu XML e gerencie-a facilmente, pois é umadict
subclasse.A instalação é fácil:
pip install python-benedict
Ele suporta e normaliza operações de E / S com muitos formatos:
Base64
,CSV
,JSON
,TOML
,XML
,YAML
equery-string
.É bem testado e de código aberto no GitHub .
fonte
fonte
Se a fonte for um arquivo xml, diga como esta amostra
você pode tentar o seguinte código
Saída seria
fonte