2010-05-29 6 views
6

lors de l'utilisation des outils XML des actions de Python tels que xml.dom.minidom pour l'écriture XML, un fichier serait toujours commencer commeComment écrire un fichier XML sans en-tête en Python?

<?xml version="1.0"?>

[...]

Bien que ce soit le code XML parfaitement légal, et il est même recommandé d'utiliser l'en-tête, je voudrais m'en débarrasser comme l'un des programmes que je travaille a des problèmes ici.

Je n'arrive pas à trouver l'option appropriée dans xml.dom.minidom, donc je me suis demandé s'il y avait d'autres paquets qui permettent de négliger l'en-tête.

Cheers,

Nico

+0

Vous pouvez toujours écrire sur un objet StringIO, supprimer l'en-tête et l'enregistrer. C'est probablement plus facile que de choisir une nouvelle bibliothèque. http://docs.python.org/library/stringio.html – msw

Répondre

13

Malheureusement, minidom ne vous permet pas d'omettre la déclaration XML.

Mais vous pouvez toujours sérialiser vous-même le contenu du document en appelant le toxml() sur l'élément racine du document au lieu du document. Ensuite, vous ne serez pas obtenir une déclaration XML:

xml= document.documentElement.toxml('utf-8') 

... mais vous pouvez également ne pas obtenir quoi que ce soit d'autre en dehors de l'élément racine, comme le DOCTYPE, ou des commentaires ou des instructions de traitement. Si vous en avez besoin, serialise chaque enfant de l'objet document un par un:

xml= '\n'.join(node.toxml('utf-8') for node in document.childNodes) 

je me suis demandé s'il y a d'autres paquets qui ne permettent pas négliger l'en-tête.

DOM niveau 3 LS defines un paramètre de configuration xml-declaration vous pouvez utiliser pour supprimer. La seule implémentation Python que je connaisse est pxdom, qui est complète sur le support des standards, mais pas du tout rapide.

+1

Pour l'enregistrement, les API ElementTree LXML et Python 2.7 acceptent 'xml_declaration = False' sur' .write() 'et LXML et cElementTree sont très rapides. – ssokolow

+0

Quelques nouvelles en 2018 à "no xml-declaration"? XML semble abandonné en Python ... Utilisez Java à la place? PS: [aucun ici] (https://docs.python.org/3/library/xml.dom.minidom.html). –

0

Les puristes peuvent ne pas aimer entendre cela, mais j'ai trouvé à l'aide d'un analyseur XML pour générer XML pour être surpuissant. Il suffit de le générer directement en tant que chaînes. Cela vous permet également de générer des fichiers plus volumineux que vous ne pouvez conserver en mémoire, ce que vous ne pouvez pas faire avec DOM. Lire XML est une autre histoire.

+3

Ceci est lourd de pièges. Sérialiser le XML est plus facile que de l'analyser, mais cela demande encore beaucoup de soin. Des trucs comme les espaces qui s'échappent dans les valeurs d'attributs (pour éviter la normalisation lors de l'analyse), le problème ']]>', la division des sections CDATA (surtout si vous avez besoin d'une sortie non UTF-8) et surtout la sérialisation des DOM. Vous * allez * faire des erreurs et générer quelque chose qui n'est pas bien formé en XML. Et puis tous les enfants méchants vont rire. – bobince

0

Si vous utilisez la fonction minidom, il vous suffit de revenir dans le fichier et de supprimer la première ligne après avoir écrit tout le code XML dont vous avez besoin.

0

Vous pourriez être en mesure d'utiliser un objet de type fichier sur mesure qui supprime la première balise, par exemple:

class RemoveFirstLine: 
    def __init__(self, f): 
     self.f = f 
     self.xmlTagFound = False 

    def __getattr__(self, attr): 
     return getattr(self, self.f) 

    def write(self, s): 
     if not self.xmlTagFound: 
      x = 0 # just to be safe 
      for x, c in enumerate(s): 
       if c == '>': 
        self.xmlTagFound = True 
        break 
      self.f.write(s[x+1:]) 
     else: 
      self.f.write(s) 

... 
f = RemoveFirstLine(open('path', 'wb')) 
Node.writexml(f, encoding='UTF-8') 

ou quelque chose de similaire. Cela a l'avantage que le fichier ne doit pas être totalement réécrit si les fichiers XML sont assez volumineux.

5

Si vous souhaitez utiliser minidom et maintenir « joliesse », que diriez-vous cela comme une solution rapide/aki:

xml_without_declaration.py:

import xml.dom.minidom as xml 

doc = xml.Document() 

declaration = doc.toxml() 

a = doc.createElement("A") 
doc.appendChild(a) 
b = doc.createElement("B") 
a.appendChild(b) 

xml = doc.toprettyxml()[len(declaration):] 

print xml 
+0

Cela laisse une nouvelle ligne au début de la chaîne. Correction avec 'xml = doc.toprettyxml() [(len (déclaration) + 1):]'. –

Questions connexes