web-dev-qa-db-fra.com

Créer un fichier XML simple en utilisant python

Quelles sont mes options si je veux créer un fichier XML simple en python? (bibliothèque sage)

Le xml que je veux ressemble à:

<root>
 <doc>
     <field1 name="blah">some value1</field1>
     <field2 name="asdfasd">some vlaue2</field2>
 </doc>

</root>
126
Blankman

De nos jours, l’option la plus populaire (et très simple) est l’API ElementTree , , Qui est incluse dans la bibliothèque standard depuis Python 2.5.

Les options disponibles pour cela sont:

  • ElementTree (implémentation élémentaire d’ElementTree en Python. Partie de la bibliothèque standard depuis la version 2.5)
  • cElementTree (implémentation C optimisée de ElementTree. Aussi offert dans la bibliothèque standard depuis la version 2.5)
  • LXML (basé sur libxml2. Offre un sur-ensemble riche de l'API ElementTree ainsi que XPath, des sélecteurs CSS, etc.)

Voici un exemple de la façon de générer votre exemple de document à l’aide de in-stdlib cElementTree:

import xml.etree.cElementTree as ET

root = ET.Element("root")
doc = ET.SubElement(root, "doc")

ET.SubElement(doc, "field1", name="blah").text = "some value1"
ET.SubElement(doc, "field2", name="asdfasd").text = "some vlaue2"

tree = ET.ElementTree(root)
tree.write("filename.xml")

Je l'ai testé et cela fonctionne, mais je suppose que les espaces ne sont pas significatifs. Si vous avez besoin de l'indentation "prettyprint", faites-le-moi savoir et je vérifierai comment faire. (Cela peut être une option spécifique à LXML. Je n'utilise pas beaucoup l'implémentation de stdlib)

Pour en savoir plus, voici quelques liens utiles:

Pour finir, cElementTree ou LXML devrait être assez rapide pour répondre à tous vos besoins (tous deux sont du code C optimisé), mais si vous vous trouvez dans une situation où vous devez extraire toute la performance, les tests de performance le site LXML indique que:

  • LXML gagne clairement pour la sérialisation (génération) de XML
  • LXML est un peu plus lent que cElementTree pour l'analyse.
236
ssokolow

La bibliothèque lxml inclut une syntaxe très pratique pour la génération XML, appelée E-factory . Voici comment je donnerais l'exemple que vous donnez:

#!/usr/bin/python
import lxml.etree
import lxml.builder    

E = lxml.builder.ElementMaker()
ROOT = E.root
DOC = E.doc
FIELD1 = E.field1
FIELD2 = E.field2

the_doc = ROOT(
        DOC(
            FIELD1('some value1', name='blah'),
            FIELD2('some value2', name='asdfasd'),
            )   
        )   

print lxml.etree.tostring(the_doc, pretty_print=True)

Sortie:

<root>
  <doc>
    <field1 name="blah">some value1</field1>
    <field2 name="asdfasd">some value2</field2>
  </doc>
</root>

Il prend également en charge l’ajout à un nœud déjà créé, par exemple. après ce qui précède, vous pourriez dire

the_doc.append(FIELD2('another value again', name='hithere'))
55
rescdsk

Yattag http://www.yattag.org/ ou https://github.com/leforestier/yattag fournit une API intéressante pour créer un tel document XML (ainsi que des documents HTML).

Il utilise gestionnaire de contexte et with mot-clé.

from yattag import Doc, indent

doc, tag, text = Doc().tagtext()

with tag('root'):
    with tag('doc'):
        with tag('field1', name='blah'):
            text('some value1')
        with tag('field2', name='asdfasd'):
            text('some value2')

result = indent(
    doc.getvalue(),
    indentation = ' '*4,
    newline = '\r\n'
)

print(result)

alors vous aurez:

<root>
    <doc>
        <field1 name="blah">some value1</field1>
        <field2 name="asdfasd">some value2</field2>
    </doc>
</root>
13
scls

Pour le choix le plus simple, j'irais avec minidom: http://docs.python.org/library/xml.dom.minidom.html . Il est intégré à la bibliothèque standard Python et est facile à utiliser dans des cas simples.

Voici un tutoriel assez facile à suivre: http://www.boddie.org.uk/python/XML_intro.html

6
whaley

Pour une structure XML aussi simple, vous souhaiterez peut-être ne pas impliquer un module XML complet. Considérons un modèle de chaîne pour les structures les plus simples, ou Jinja pour quelque chose d'un peu plus complexe. Jinja peut gérer la lecture en boucle d'une liste de données pour produire le xml interne de votre liste de documents. C'est un peu plus délicat avec les modèles de chaînes python bruts

Pour un exemple en Jinja, voir ma réponse à une question similaire .

Voici un exemple de génération de votre XML avec des modèles de chaîne.

import string
from xml.sax.saxutils import escape

inner_template = string.Template('    <field${id} name="${name}">${value}</field${id}>')

outer_template = string.Template("""<root>
 <doc>
${document_list}
 </doc>
</root>
 """)

data = [
    (1, 'foo', 'The value for the foo document'),
    (2, 'bar', 'The <value> for the <bar> document'),
]

inner_contents = [inner_template.substitute(id=id, name=name, value=escape(value)) for (id, name, value) in data]
result = outer_template.substitute(document_list='\n'.join(inner_contents))
print result

Sortie: 

<root>
 <doc>
    <field1 name="foo">The value for the foo document</field1>
    <field2 name="bar">The &lt;value&gt; for the &lt;bar&gt; document</field2>
 </doc>
</root>

L'approche basée sur les modèles est que vous n'obtiendrez pas l'échappement de < et > gratuitement. J'ai dansé autour de ce problème en tirant un util de xml.sax

3
bigh_29

Je viens juste de finir d'écrire un générateur XML, en utilisant la méthode des modèles de bigh_29 ... c'est un moyen agréable de contrôler ce que vous produisez sans trop d'objets Objets "gênants".

En ce qui concerne la balise et la valeur, j’ai utilisé deux tableaux, l’un donnant le nom et la position de la balise dans le fichier xml en sortie, et l’autre référençant un fichier de paramètres contenant la même liste de balises. Cependant, le fichier de paramètres a également le numéro de position dans le fichier d’entrée (csv) correspondant à partir duquel les données seront extraites de . De cette manière, si la position des données provenant du fichier d’entrée est modifiée, le programme ne change pas; il détermine de manière dynamique la position du champ de données à partir de la balise appropriée dans le fichier de paramètres.

0
Cloughie

Les balises et les valeurs doivent être utilisées avant l’arrêt et au point que cela fonctionne. Je l'ai fait avant que je trouve mon code pour montrer comme exemple.

en attendant trouver plus d'infos ici- https://www.w3schools.com/php/

0
John