Comment mettre à jour/modifier un fichier XML en python?

j'ai un document XML que je voudrais mettre à jour après qu'il contienne déjà des données.

j'ai pensé à ouvrir le fichier XML en mode" a " (ajout). Le problème est que les nouvelles données seront écrites après la racine balise de fermeture.

Comment puis-je supprimer la dernière ligne d'un fichier, puis commencer à écrire des données à partir de ce point, puis fermer la balise racine?

bien sûr j'ai pu lire l'ensemble du dossier et faire quelques manipulations de chaînes, mais je ne pense pas que c'est la meilleure idée..

Merci pour votre temps.

17
demandé sur ndmeiri 2009-10-20 02:52:30

8 réponses

la voie rapide et facile, que vous certainement ne devrait pas faire (voir ci-dessous), est de lire le fichier entier dans une liste de chaînes en utilisant readlines (). J'écris ceci au cas où la solution rapide et facile est ce que vous cherchez.

ouvrez simplement le fichier en utilisant open(), puis appelez la méthode readlines (). Ce que vous obtiendrez une liste de toutes les chaînes dans le fichier. Maintenant, vous pouvez facilement ajouter des chaînes avant le dernier élément (il suffit d'ajouter à la liste un élément avant la dernière). Enfin, vous pouvez les écrire de nouveau dans le fichier en utilisant writelines().

un exemple pourrait aider:

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)

La raison pour laquelle vous ne devriez pas faire cela est parce que, à moins que vous ne fassiez quelque chose de très rapide et sale, vous devriez utiliser un parses XML. Il s'agit d'une bibliothèque qui vous permet de travailler avec XML intelligemment, en utilisant des concepts tels que DOM, trees et nodes. Ce n'est pas seulement la bonne façon de travailler avec XML, c'est aussi la manière standard, ce qui rend votre code plus portable, et plus facile à comprendre pour les autres programmeurs.

la réponse de Tim mentionnait la vérification http://docs.python.org/library/xml.dom.minidom.html dans ce but, ce qui, je pense, serait une excellente idée.

4
répondu Edan Maor 2009-10-19 23:06:21

en utilisant 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')

remarque: la production écrite file_new.xml pour vous d'expérimenter, en écrivant à file.xml remplacer l'ancien contenu.

IMPORTANT: la bibliothèque ElementTree stocke les attributs dans un dict, comme tel, L'ordre dans lequel ces attributs sont listés dans le texte xml ne sera pas préservé. Au lieu de cela, ils seront produits dans l'ordre alphabétique. (aussi, les commentaires sont supprimés. Je trouve cela plutôt ennuyeux)

ie: le texte d'entrée xml <b y='xxx' x='2'>some body</b> sortie <b x='2' y='xxx'>some body</b>(après alphabetising des paramètres de la commande sont définis)

cela signifie qu'en propageant l'original et les fichiers modifiés dans un système de contrôle de révision (tel que SVN, CSV, ClearCase, etc.), une différence entre les 2 fichiers peut ne pas sembler jolie.

47
répondu FraggaMuffin 2015-07-14 14:14:51

parseurs XML Python utiles:

  1. Minidom - fonctionnelle mais limitée
  2. ElementTree - performance décente, plus de fonctionnalité
  3. lxml - haute performance dans la plupart des cas, haute fonctionnalité incluant le support de real xpath

tout cela est mieux que d'essayer de mettre à jour le fichier XML comme chaînes de texte.

Ce que cela signifie pour vous:

ouvert votre fichier avec un analyseur XML de votre choix, trouvez le noeud qui vous intéresse, remplacez la valeur, sérialisez le fichier.

17
répondu Gabriel Hurley 2015-04-14 20:12:28

bien que je sois D'accord avec Tim et Oben Sonne que vous devriez utiliser une bibliothèque XML, il y a encore des moyens de la manipuler comme un simple objet string.

Je n'essaierais probablement pas d'utiliser un seul pointeur de fichier pour ce que vous décrivez, et à la place lire le fichier dans la mémoire, l'éditer, puis l'écrire.:

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
répondu John Paulett 2009-10-30 07:34:59

ce que vous voulez vraiment faire, c'est utiliser un analyseur XML et ajouter les nouveaux éléments avec L'API fournie.

il suffit alors de réécrire le fichier.

le plus facile à utiliser serait probablement un DOM parser comme celui ci-dessous:

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

1
répondu Tim 2009-10-19 22:58:47

Pour rendre ce processus plus robuste, vous pourriez envisager d'utiliser l'analyseur SAX (de cette façon, vous n'avez pas à tenir tout le fichier en mémoire), lire et écrire jusqu'à la fin de l'arbre, et puis commencer ajoutant.

1
répondu jldupont 2009-10-19 23:38:53

vous devriez lire le fichier XML en utilisant des modules XML spécifiques. De cette façon, vous pouvez modifier le document XML en mémoire et réécrire votre document XML modifié dans le fichier.

Voici un début rapide: http://docs.python.org/library/xml.dom.minidom.html

il y a beaucoup d'autres utilitaires XML, dont l'un dépend de la nature de votre fichier XML et de quelle manière vous voulez l'éditer.

0
répondu Oben Sonne 2009-10-19 23:00:33

comme L'a expliqué Edan Maor, la façon rapide et sale de le faire (pour [utc-16] encodé .fichiers xml), vous devez faire pour les résons expliqués par Edam Maor, peut être fait avec le code python 2.7 suivant dans le cas où les contraintes de temps ne vous permettent pas d'apprendre les parses XML (propper).

en Supposant que vous voulez:

  1. supprimer la dernière ligne du fichier xml original.
  2. Ajouter une ligne
  3. remplacer une ligne
  4. Fermer la racine balise.

cela a fonctionné en python 2.7 modifiant an .fichier xml nommé "b.xml" situé dans le dossier "a", où "a" est situé dans le "dossier de travail" de python. Il affiche le nouveau fichier modifié "c.xml" dans le dossier "a", sans céder les erreurs d'encodage (pour moi) en plus de l'utiliser en dehors de 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
répondu a.t. 2018-01-04 02:36:54