Como actualizar/modificar um ficheiro XML em python?

Tenho um documento XML que gostaria de actualizar depois de já conter dados.

pensei em abrir o ficheiro XML no modo "a" (adicionar). O problema é que os novos dados serão escritos após a tag de fechamento de raiz.

Como posso apagar a última linha de um ficheiro, depois começar a escrever dados desse ponto, e depois fechar a etiqueta de raiz?

Claro que podia ler o ficheiro todo e fazer algumas manipulações de cordas, mas não acho que seja o melhor. ideia..

Obrigado pelo seu tempo.

Author: ndmeiri, 2009-10-20

8 answers

A maneira rápida e fácil, que definitivamente não deve fazer (ver abaixo), é ler o ficheiro inteiro numa lista de cadeias de caracteres usando as linhas de leitura(). Escrevo isto para o caso de a solução fácil e rápida ser o que procura.

Basta abrir o ficheiro usando o open (), e depois chamar o método readlines (). O que você vai conseguir é uma lista de todas as cordas no arquivo. Agora, você pode facilmente adicionar strings antes do último elemento (basta adicionar à lista um elemento antes do último). Finalmente, você pode gravá-los de volta ao ficheiro usando writelines().

Um exemplo pode ajudar:

my_file = open(filename, "r")
lines_of_file = my_file.readlines()
lines_of_file.insert(-1, "This line is added one before the last line")
my_file.writelines(lines_of_file)

A razão pela qual você não deve fazer isso é porque, a menos que você esteja fazendo algo muito rápido n' dirty, você deve estar usando um XML parses. Esta é uma biblioteca que lhe permite trabalhar com XML inteligentemente, usando conceitos como DOM, árvores e nós. Esta não é apenas a maneira adequada de trabalhar com XML, é também a maneira padrão, tornando o seu código tanto mais portátil, e mais fácil para outros programadores para entender.

A resposta do Tim mencionou a saída. http://docs.python.org/library/xml.dom.minidom.html para este fim, o que acho que seria uma grande ideia.
 4
Author: Edan Maor, 2009-10-19 23:06:21

Utilizar ElementTree:

import xml.etree.ElementTree

# Open original file
et = xml.etree.ElementTree.parse('file.xml')

# Append new tag: <a x='1' y='abc'>body text</a>
new_tag = xml.etree.ElementTree.SubElement(et.getroot(), 'a')
new_tag.text = 'body text'
new_tag.attrib['x'] = '1' # must be str; cannot be an int
new_tag.attrib['y'] = 'abc'

# Write back to file
#et.write('file.xml')
et.write('file_new.xml')

Nota: o resultado escrito em file_new.xml para que possa experimentar, escrever de volta a file.xml irá substituir o conteúdo antigo.

Importante: a Biblioteca ElementTree armazena atributos em um dict, como tal, a ordem pela qual esses atributos estão listados no texto xml não será preservada. Em vez disso, serão produzidos por ordem alfabética. (além disso, os comentários são removidos. Acho isto bastante irritante.

Ie: o texto de entrada xml <b y='xxx' x='2'>some body</b> será o resultado como <b x='2' y='xxx'>some body</b> (Depois de alfabetizar os parâmetros de ordem são definidos)

Isto significa que ao enviar o original e alterar os ficheiros para um sistema de controlo de revisões (como SVN, CSV, ClearCase, etc), uma diferença entre os 2 Ficheiros pode não parecer bonita.

 47
Author: FraggaMuffin, 2015-07-14 14:14:51

Analisadores de XML em Python úteis:

  1. Minidom - funcional mas limitado
  2. ElementTree - desempenho decente, mais funcionalidade
  3. lxml - alto desempenho na maioria dos casos , alta funcionalidade incluindo suporte real de xpath

Qualquer um desses é melhor do que tentar atualizar o arquivo XML como strings de texto.

O que isso significa para ti:

Abra o seu ficheiro com um analisador XML à sua escolha, encontre a nó em que você está interessado, substituir o valor, serializar o arquivo de volta.

 17
Author: Gabriel Hurley, 2015-04-14 20:12:28

Embora eu concorde com Tim e Oben Sonne que você deve usar uma biblioteca XML, existem maneiras de ainda manipulá-la como um objeto de texto simples.

Eu provavelmente não iria tentar usar um único ponteiro de arquivo para o que você está descrevendo, e em vez disso ler o arquivo em memória, editá-lo, em seguida, escrevê-lo para fora.:

inFile = open('file.xml', 'r')
data = inFile.readlines()
inFile.close()
# some manipulation on `data`
outFile = open('file.xml', 'w')
outFile.writelines(data)
outFile.close()
 3
Author: John Paulett, 2009-10-30 07:34:59

O que você realmente quer fazer é usar um analisador XML e adicionar os novos elementos com a API fornecida.

Então simplesmente sobrepõe o ficheiro.

O mais fácil de usar seria provavelmente um analisador DOM como o abaixo:

Http://docs.python.org/library/xml.dom.minidom.html

 1
Author: Tim, 2009-10-19 22:58:47

Para tornar este processo mais robusto, você poderia considerar a utilização do analisador SAX (dessa forma você não tem que manter todo o arquivo em memória), ler e escrever até o final da árvore e, em seguida, começar a adicionar.

 1
Author: jldupont, 2009-10-19 23:38:53

Deve ler o ficheiro XML usando módulos XML específicos. Dessa forma, você pode editar o documento XML na memória e reescrever o seu documento XML alterado para o arquivo.

Aqui está um começo rápido: http://docs.python.org/library/xml.dom.minidom.html

Existem muitos outros utilitários XML, que é o melhor depende da natureza do seu ficheiro XML e de que forma o deseja editar.

 0
Author: Oben Sonne, 2009-10-19 23:00:33

Como Edan Maor explicou, a forma rápida e suja de o fazer (para [utc-16] codificado .ficheiros xml), o que deverá NÃO Fazer para os resons que o Edam Maor explicou, poderá fazer com o seguinte código python 2.7, no caso de as restrições de tempo não lhe permitirem aprender os parágrafos XML (proxper).

Assumindo que queres:

  1. apaga a última linha do ficheiro xml original.
  2. Adicionar uma linha
  3. substituir uma linha
  4. fecha a etiqueta raiz.

It trabalhou em python 2.7 modificando an .ficheiro xml chamado "b.xml" localizado na pasta "a", onde" a "estava localizado na" pasta de trabalho " do python. Ele emite o novo arquivo modificado como "c.xml" in folder "a", without yielding encoding errors (for me) in further use outside of python 2.7.

pattern = '<Author>'
subst = '    <Author>' + domain + '\\' + user_name + '</Author>'
line_index =0 #set line count to 0 before starting
file = io.open('a/b.xml', 'r', encoding='utf-16')
lines = file.readlines()
outFile = open('a/c.xml', 'w')
for line in lines[0:len(lines)]:
    line_index =line_index +1
    if line_index == len(lines):
        #1. & 2. delete last line and adding another line in its place not writing it
        outFile.writelines("Write extra line here" + '\n')
        # 4. Close root tag:
        outFile.writelines("</phonebook>") # as in:
        #http://tizag.com/xmlTutorial/xmldocument.php
    else:
        #3. Substitue a line if it finds the following substring in a line:
        pattern = '<Author>'
        subst = '    <Author>' + domain + '\\' + user_name + '</Author>'
        if pattern in line:
            line = subst
            print line
        outFile.writelines(line)#just writing/copying all the lines from the original xml except for the last.
 0
Author: a.t., 2018-01-04 02:36:54