wake-up-neo.com

Eine einfache XML-Datei mit Python erstellen

Was sind meine Optionen, wenn ich eine einfache XML-Datei in Python erstellen möchte? (bibliothekarisch)

Die XML, die ich möchte, sieht folgendermaßen aus:

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

</root>
126
Blankman

Die populärste (und sehr einfache) Option ist heutzutage die ElementTree API , , Die seit Python 2.5 in der Standardbibliothek enthalten ist.

Die verfügbaren Optionen dafür sind:

  • ElementTree (Basic, pure-Python-Implementierung von ElementTree. Teil der Standardbibliothek seit 2.5)
  • cElementTree (Optimierte C-Implementierung von ElementTree. Seit 2.5 auch in der Standardbibliothek verfügbar)
  • LXML (Basierend auf libxml2. Bietet eine reichhaltige Obermenge der ElementTree-API sowie XPath, CSS-Selektoren und mehr)

Hier ein Beispiel, wie Sie ein Beispieldokument mit dem in-stdlib cElementTree erstellen:

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")

Ich habe es getestet und es funktioniert, aber ich gehe davon aus, dass Leerzeichen keine Rolle spielen. Wenn Sie eine "Prettyprint" -Einrückung benötigen, lassen Sie es mich wissen und ich schaue nach, wie das geht. (Möglicherweise handelt es sich um eine LXML-spezifische Option. Ich verwende die stdlib-Implementierung nicht viel.)

Hier finden Sie einige nützliche Links:

Als letzte Bemerkung sollte entweder cElementTree oder LXML für alle Ihre Anforderungen schnell genug sein (beide sind optimierter C-Code). Falls Sie sich jedoch in einer Situation befinden, in der Sie bis zum letzten Moment Leistung abschneiden müssen, werden die Benchmarks berücksichtigt Auf der LXML-Site wird Folgendes angezeigt:

  • LXML gewinnt eindeutig für die Serialisierung (Generierung) von XML
  • Als Nebeneffekt bei der Implementierung einer korrekten übergeordneten Traversierung ist LXML für die Analyse etwas langsamer als cElementTree.
236
ssokolow

Die lxml-Bibliothek enthält eine sehr praktische Syntax für die XML-Generierung, die als E-factory bezeichnet wird. So würde ich das Beispiel machen, das Sie geben:

#!/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)

Ausgabe:

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

Es unterstützt auch das Hinzufügen zu einem bereits erstellten Knoten, z. nach dem oben konnte man sagen

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

Yattag http://www.yattag.org/ oder https://github.com/leforestier/yattag bietet eine interessante API zum Erstellen von XML-Dokumenten (und auch HTML-Dokumenten).

Es verwendet das Schlüsselwort context manager und with.

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)

so wirst du bekommen:

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

Für die einfachste Wahl würde ich mit minidom gehen: http://docs.python.org/library/xml.dom.minidom.html . Es ist in die Python-Standardbibliothek integriert und in einfachen Fällen einfach zu verwenden.

Hier ist ein ziemlich einfaches Tutorial: http://www.boddie.org.uk/python/XML_intro.html

6
whaley

Für eine solche einfache XML-Struktur möchten Sie möglicherweise kein volles XML-Modul verwenden. Betrachten Sie eine Stringvorlage für die einfachsten Strukturen oder Jinja für etwas komplexeres. Jinja kann eine Schleife mit einer Datenliste ausführen, um die innere XML-Datei Ihrer Dokumentliste zu erstellen. Das ist bei rohen Python-String-Vorlagen etwas komplizierter

Für ein Jinja-Beispiel siehe meine Antwort auf eine ähnliche Frage .

Hier ein Beispiel zum Generieren Ihrer XML-Datei mit Stringvorlagen.

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

Ausgabe: 

<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>

Der Nachteil des Vorlagenansatzes ist, dass < und > nicht kostenlos umgangen werden können. Ich habe um dieses Problem herumgetanzt, indem ich ein util von xml.sax eingezogen habe.

3
bigh_29

Ich habe gerade mit dem Erstellen eines XML-Generators fertiggearbeitet und die Methode von bigh_29 mit Vorlagen verwendet. Dies ist eine schöne Möglichkeit, die Ausgabe zu steuern, ohne dass zu viele Objekte in den Weg kommen.

Für das Tag und den Wert habe ich zwei Arrays verwendet, eines davon, das den Tagnamen und die Position in der Ausgabe-XML angibt, und eines, das auf eine Parameterdatei mit derselben Liste von Tags verweist. Die Parameterdatei hat jedoch auch die Positionsnummer in der entsprechenden Eingabedatei (CSV-Datei), aus der die Daten aus ..__ übernommen werden. das Programm ändert sich nicht; er ermittelt dynamisch die Datenfeldposition aus dem entsprechenden Tag in der Parameterdatei.

0
Cloughie

Tags und Werte müssen vorzeitig verwendet werden, damit dies funktioniert. Ich habe das getan, bevor ich meinen Code als Beispiel finden werde.

weitere Informationen finden Sie hier- https://www.w3schools.com/php/

0
John