35 Stimmen

XML-Schreibwerkzeuge für Python

Ich bin derzeit versuchen ElementTree und es sieht gut aus, es escapes HTML-Entitäten und so weiter und so fort. Verpasse ich etwas wirklich wundervolles, von dem ich noch nichts gehört habe?

Das ist ähnlich wie das, was ich gerade mache:

import xml.etree.ElementTree as ET
root = ET.Element('html')
head = ET.SubElement(root,'head')
script = ET.SubElement(head,'script')
script.set('type','text/javascript')
script.text = "var a = 'I love á letters'"
body = ET.SubElement(root,'body')
h1 = ET.SubElement(body,'h1')
h1.text = "And I like the fact that 3 > 1"
tree = ET.ElementTree(root)
tree.write('foo.xhtml')

# more foo.xhtml
<html><head><script type="text/javascript">var a = 'I love &amp;aacute;
letters'</script></head><body><h1>And I like the fact that 3 &gt; 1</h1>
</body></html>

0 Stimmen

Einige der Web-Template-Sprachen (die natürlich HTML / XML erzeugen) können als Module geladen werden, ohne dass ein begleitendes Web-Framework benötigt wird. Wenn Sie etwas Ausgefallenes brauchen, würde ich vorschlagen, in diese Richtung zu gehen. Ich habe besonders gute Erfahrungen mit genshi gemacht.

28voto

Peter Hoffmann Punkte 52200

Eine andere Möglichkeit ist die Verwendung der E Fabrik Builder von lxml (verfügbar in Elementtree zu)

>>> from lxml import etree

>>> from lxml.builder import E

>>> def CLASS(*args): # class is a reserved word in Python
...     return {"class":' '.join(args)}

>>> html = page = (
...   E.html(       # create an Element called "html"
...     E.head(
...       E.title("This is a sample document")
...     ),
...     E.body(
...       E.h1("Hello!", CLASS("title")),
...       E.p("This is a paragraph with ", E.b("bold"), " text in it!"),
...       E.p("This is another paragraph, with a", "\n      ",
...         E.a("link", href="http://www.python.org"), "."),
...       E.p("Here are some reserved characters: <spam&egg>."),
...       etree.XML("<p>And finally an embedded XHTML fragment.</p>"),
...     )
...   )
... )

>>> print(etree.tostring(page, pretty_print=True))
<html>
  <head>
    <title>This is a sample document</title>
  </head>
  <body>
    <h1 class="title">Hello!</h1>
    <p>This is a paragraph with <b>bold</b> text in it!</p>
    <p>This is another paragraph, with a
      <a href="http://www.python.org">link</a>.</p>
    <p>Here are some reservered characters: &lt;spam&amp;egg&gt;.</p>
    <p>And finally an embedded XHTML fragment.</p>
  </body>
</html>

0 Stimmen

In meinem Fall funktioniert es nicht, da die Option pretty_print nicht vorhanden ist.

24voto

oasisbob Punkte 409

Es gibt immer SimpleXMLWriter , Teil des ElementTree-Toolkits. Die Schnittstelle ist sehr einfach.

Hier ist ein Beispiel:

from elementtree.SimpleXMLWriter import XMLWriter
import sys

w = XMLWriter(sys.stdout)
html = w.start("html")

w.start("head")
w.element("title", "my document")
w.element("meta", name="generator", value="my application 1.0")
w.end()

w.start("body")
w.element("h1", "this is a heading")
w.element("p", "this is a paragraph")

w.start("p")
w.data("this is ")
w.element("b", "bold")
w.data(" and ")
w.element("i", "italic")
w.data(".")
w.end("p")

w.close(html)

0 Stimmen

Dies führt zu der Fehlermeldung: File "C:\Python33\lib\site-packages\elementtree\SimpleXMLWriter.p‌​y", line 119, in <module> def escape_cdata(s, encoding=None, replace=string.replace): AttributeError: 'module' object has no attribute 'replace'

10voto

Eli Courtwright Punkte 174547

Ich gehe davon aus, dass Sie tatsächlich einen XML-DOM-Baum erstellen, weil Sie überprüfen wollen, dass das, was in diese Datei geht, gültiges XML ist, da Sie sonst nur eine statische Zeichenfolge in eine Datei schreiben würden. Wenn die Validierung Ihrer Ausgabe tatsächlich Ihr Ziel ist, dann würde ich vorschlagen

from xml.dom.minidom import parseString

doc = parseString("""<html>
    <head>
        <script type="text/javascript">
            var a = 'I love &amp;aacute; letters'
        </script>
    </head>
    <body>
        <h1>And I like the fact that 3 &gt; 1</h1>
    </body>
    </html>""")

with open("foo.xhtml", "w") as f:
    f.write( doc.toxml() )

So können Sie einfach das XML schreiben, das Sie ausgeben möchten, überprüfen, ob es korrekt ist (da parseString eine Exception auslöst, wenn es ungültig ist) und Ihren Code viel schöner aussehen lassen.

Vermutlich schreiben Sie nicht einfach jedes Mal dasselbe statische XML und wollen eine gewisse Ersetzung. In diesem Fall würde ich Zeilen haben wie

var a = '%(message)s'

und verwenden Sie dann den %-Operator, um die Ersetzung vorzunehmen, etwa

</html>""" % {"message": "I love &amp;aacute; letters"})

0 Stimmen

Die Idee ist, dass der Code gültiges XML ausgibt, auch wenn ich ihm ungültiges XML gebe, wie es ET tut.

7voto

Mikhail Korobov Punkte 21059

https://github.com/galvez/xmlwitch :

import xmlwitch
xml = xmlwitch.Builder(version='1.0', encoding='utf-8')
with xml.feed(xmlns='http://www.w3.org/2005/Atom'):
    xml.title('Example Feed')
    xml.updated('2003-12-13T18:30:02Z')
    with xml.author:
        xml.name('John Doe')
    xml.id('urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6')
    with xml.entry:
        xml.title('Atom-Powered Robots Run Amok')
        xml.id('urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a')
        xml.updated('2003-12-13T18:30:02Z')
        xml.summary('Some text.')
print(xml)

4voto

Daren Thomas Punkte 64742

Wollen Sie nicht eigentlich etwas wie:

html(head(script(type='text/javascript', content='var a = ...')),
body(h1('And I like the fact that 3 < 1'), p('just some paragraph'))

Ich glaube, ich habe so etwas schon einmal gesehen. Das wäre wunderbar.

EDIT: Tatsächlich habe ich heute eine Bibliothek geschrieben, um genau das : magictree

Sie können ihn wie folgt verwenden:

from magictree import html, head, script, body, h1, p
root = html(
         head(
           script('''var a = 'I love &amp;aacute; letters''', 
                  type='text/javascript')),
         body(
           h1('And I like the fact that 3 > 1')))

# root is a plain Element object, like those created with ET.Element...
# so you can write it out using ElementTree :)
tree = ET.ElementTree(root)
tree.write('foo.xhtml')

Die Magie in magictree liegt darin, wie das Importieren funktioniert: Die Element Fabriken werden bei Bedarf erstellt. Haben eine die Quelle ansehen ist es basierend auf einer Antwort auf eine andere StackOverflow-Frage .

0 Stimmen

Ist es möglich, den Elementen Attribute hinzuzufügen? Ich meine die html/xml-Attribute wie z.B. <h1 class="something">

0 Stimmen

Yep: alle Schlüsselwortargumente werden zu Attributen, ebenso wie alle übergebenen Wörterbücher :)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X