Pergunta

Estou prestes a construir uma parte de um projeto que precisará construir e postar um documento XML em um serviço web e gostaria de fazê-lo em Python, como forma de expandir minhas habilidades nele.

Infelizmente, embora eu conheça bastante bem o modelo XML em .NET, não tenho certeza de quais são os prós e os contras dos modelos XML em Python.

Alguém tem experiência em processamento de XML em Python?Por onde você sugere que eu comece?Os arquivos XML que irei construir serão bastante simples.

Foi útil?

Solução

Pessoalmente, experimentei várias opções integradas em um projeto com muito XML e decidi por pulldom como a melhor escolha para documentos menos complexos.

Especialmente para coisas pequenas e simples, gosto da teoria de análise baseada em eventos, em vez de configurar uma série de retornos de chamada para uma estrutura relativamente simples. Aqui está uma boa discussão rápida sobre como usar a API.

O que eu gosto:você pode lidar com a análise em um for loop em vez de usar retornos de chamada.Você também atrasa a análise completa (a parte "puxar") e só obtém detalhes adicionais quando liga expandNode().Isso satisfaz meu requisito geral de eficiência “responsável” sem sacrificar a facilidade de uso e a simplicidade.

Outras dicas

ElementoÁrvore tem uma bela API python.Acho que até foi enviado como parte do python 2.5

É em python puro e, como eu disse, muito bom, mas se você precisar de mais desempenho, então lxml expõe a mesma API e usa libxml2 nos bastidores.Teoricamente, você pode simplesmente trocá-lo quando descobrir que precisa dele.

Existem 3 maneiras principais de lidar com XML, em geral:dom, sax e xpath.O modelo dom é bom se você puder carregar todo o arquivo xml na memória de uma só vez, e não se importar em lidar com estruturas de dados e estiver analisando grande parte/a maior parte do modelo.O modelo sax é ótimo se você se preocupa apenas com algumas tags e/ou está lidando com arquivos grandes e pode processá-los sequencialmente.O modelo xpath é um pouco de cada - você pode escolher caminhos para os elementos de dados necessários, mas requer mais bibliotecas para usar.

Se você deseja algo simples e empacotado com Python, minidom é a sua resposta, mas é muito ruim, e a documentação é "aqui estão os documentos sobre dom, vá descobrir".É realmente irritante.

Pessoalmente, gosto do cElementTree, que é uma implementação mais rápida (baseada em C) do ElementTree, que é um modelo semelhante ao dom.

Eu usei sistemas de sax e, em muitos aspectos, eles são mais "pitônicos" em sua aparência, mas geralmente acabo criando sistemas baseados em estados para lidar com eles, e dessa forma reside a loucura (e os bugs).

Eu digo: vá com minidom se você gosta de pesquisa, ou ElementTree se quiser um bom código que funcione bem.

Usei o ElementTree para vários projetos e recomendo.

É python, vem 'na caixa' com Python 2.5, incluindo a versão c cElementTree (xml.etree.cElementTree) que é 20 vezes mais rápida que a versão Python pura e é muito fácil de usar.

lxml tem algumas vantagens de desempenho, mas elas são desiguais e você deve verificar primeiro os benchmarks para seu caso de uso.

Pelo que entendi, o código ElementTree pode ser facilmente portado para lxml.

Depende um pouco de quão complicado o documento precisa ser.

Eu usei muito o minidom para escrever XML, mas geralmente isso consiste apenas em ler documentos, fazer algumas transformações simples e escrevê-los novamente.Isso funcionou bem até que eu precisei da capacidade de ordenar atributos de elementos (para satisfazer um aplicativo antigo que não analisa XML corretamente).Nesse ponto desisti e escrevi o XML sozinho.

Se você estiver trabalhando apenas em documentos simples, fazer isso sozinho pode ser mais rápido e simples do que aprender uma estrutura.Se você puder escrever o XML manualmente, provavelmente também poderá codificá-lo manualmente (apenas lembre-se de escapar corretamente dos caracteres especiais e usar str.encode(codec, errors="xmlcharrefreplace")).Além dessas confusões, o XML é regular o suficiente para que você não precisar uma biblioteca especial para escrevê-lo.Se o documento for muito complicado para ser escrito à mão, você provavelmente deverá consultar uma das estruturas já mencionadas.Em nenhum momento você precisará escrever um gravador XML geral.

Você também pode tentar desembaraçar para analisar documentos XML simples.

Como você mencionou que criará um XML "bastante simples", o módulo minidom (parte da Biblioteca Padrão Python) provavelmente atenderá às suas necessidades.Se você tiver alguma experiência com a representação DOM de XML, deverá achar a API bastante simples.

Eu escrevo um servidor SOAP que recebe solicitações XML e cria respostas XML.(Infelizmente não é meu projeto, então é de código fechado, mas isso é outro problema).

Descobri que criar documentos XML (SOAP) é bastante simples se você tiver uma estrutura de dados que "se ajuste" ao esquema.

Guardo o envelope porque o envelope de resposta é (quase) igual ao envelope de solicitação.Então, como minha estrutura de dados é um dicionário (possivelmente aninhado), crio uma string que transforma esse dicionário em itens <key>valor</key>.

Essa é uma tarefa que a recursão simplifica e acabo com a estrutura correta.Tudo isso é feito em código python e atualmente é rápido o suficiente para uso em produção.

Você também pode criar listas (relativamente) facilmente, embora, dependendo do seu cliente, você possa encontrar problemas, a menos que forneça dicas de comprimento.

Para mim, isso foi muito mais simples, já que um dicionário é uma maneira muito mais fácil de trabalhar do que alguma classe customizada.Para os livros, gerar XML é muito mais fácil do que analisar!

Para um trabalho sério com XML em Python, use lxml

Python vem com a biblioteca interna ElementTree, mas lxml a estende em termos de velocidade e funcionalidade (validação de esquema, análise de sax, XPath, vários tipos de iteradores e muitos outros recursos).

Você tem que instalá-lo, mas em muitos lugares já é considerado parte do equipamento padrão (por exemplo,O Google AppEngine não permite pacotes Python baseados em C, mas abre uma exceção para lxml, pyyaml ​​e alguns outros).

Construindo documentos XML com E-factory (de lxml)

Sua pergunta é sobre a construção de um documento XML.

Com o lxml existem muitos métodos e demorei um pouco para encontrar aquele que parece ser fácil de usar e também de ler.

Exemplo de código de documento lxml sobre como usar o E-factory (ligeiramente simplificado):


O E-factory fornece uma sintaxe simples e compacta para gerar XML e HTML:

>>> from lxml.builder import E

>>> html = page = (
...   E.html(       # create an Element called "html"
...     E.head(
...       E.title("This is a sample document")
...     ),
...     E.body(
...       E.h1("Hello!"),
...       E.p("This is a paragraph with ", E.b("bold"), " text in it!"),
...       E.p("This is another paragraph, with a", "\n      ",
...         E.a("link", href="http://www.python.org"), "."),
...       E.p("Here are some reserved characters: <spam&egg>."),
...     )
...   )
... )

>>> print(etree.tostring(page, pretty_print=True))
<html>
  <head>
    <title>This is a sample document</title>
  </head>
  <body>
    <h1>Hello!</h1>
    <p>This is a paragraph with <b>bold</b> text in it!</p>
    <p>This is another paragraph, with a
      <a href="http://www.python.org">link</a>.</p>
    <p>Here are some reserved characters: &lt;spam&amp;egg&gt;.</p>
  </body>
</html>

Eu aprecio no E-factory seguir as coisas

O código é lido quase como o documento XML resultante

A legibilidade conta.

Permite a criação de qualquer conteúdo XML

Suporta coisas como:

  • uso de namespaces
  • iniciando e terminando nós de texto dentro de um elemento
  • funções que formatam o conteúdo do atributo (veja func CLASS em amostra lxml completa)

Permite construções muito legíveis com listas

por exemplo.:

from lxml import etree
from lxml.builder import E
lst = ["alfa", "beta", "gama"]
xml = E.root(*[E.record(itm) for itm in lst])
etree.tostring(xml, pretty_print=True)

resultando em:

<root>
  <record>alfa</record>
  <record>beta</record>
  <record>gama</record>
</root>

Conclusões

Eu recomendo fortemente a leitura do tutorial lxml - ele está muito bem escrito e lhe dará muitos outros motivos para usar esta poderosa biblioteca.

A única desvantagem do lxml é que ele deve ser compilado.Ver Então responda para mais dicas como instalar o lxml do pacote de formato wheel em uma fração de segundo.

Se você pretende criar mensagens SOAP, confira sabonetelib.Ele usa ElementTree internamente, mas fornece uma interface muito mais limpa para serializar e desserializar mensagens.

Eu recomendo fortemente SAX - Simple API for XML - implementação nas bibliotecas Python.Eles são bastante fáceis de configurar e processar grandes XML mesmo conduzido API, conforme discutido por postadores anteriores aqui, e têm baixo consumo de memória, ao contrário da validação DOM estilo XML analisadores.

Presumo que o modo .Net de processar XML se baseia em alguma versão do MSXML e, nesse caso, presumo que usar, por exemplo, minidom faria você se sentir um pouco em casa.No entanto, se for um processamento simples que você está fazendo, qualquer biblioteca provavelmente servirá.

Também prefiro trabalhar com ElementTree ao lidar com xml em Python, é uma biblioteca muito bacana.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top