Seite 1 von 1

XML Templating Frage

Verfasst: Samstag 21. Januar 2006, 12:32
von Mark Fink
Jens Diemer hat mir empfohlen meine Frage hier zu posten:
...
In PyLucid habe ich mich erstmal für simpleTAL entschieden:

http://www.python-forum.de/viewtopic.php?t=4231
Ich würde dir vorschlagen, poste dein Anliegen mal im Forum, vielleicht kennt sich da
jemand mit aus!
Mark Fink schrieb:
...Ich bin auf der Suche nach einer Template Engine zur programmatischen Erstellung von XML Markup.
Genauer suche ich etwas wie Jython + XMLBuilder + Templates um Testdaten für XML Applikationen zu erstellen. Ich brauche die Templates um die Testdaten gegen Interface Changes zu immunisieren. Evtl. ist Dir bei der Studie etwas brauchbares aufgefallen? Es muss nicht unbedingt in Python sein. In erster Linie suche ich einen brauchbaren Ansatz. XSLT ist mir zuviel :-))

Verfasst: Samstag 21. Januar 2006, 12:40
von modelnine
Schon mal ElementTree angeguckt? Bietet eigentlich relativ gute Interfaces um programmatisch XML zu erstellen. Und das Template besteht dann aus einer Python-Funktion die Du mit Argumenten aufrufst, und die Dir einen Baum zurückgibt.

So würde ich es machen...

--- Heiko.

Re: XML Templating Frage

Verfasst: Samstag 21. Januar 2006, 22:15
von gerold
Mark Fink hat geschrieben:Genauer suche ich etwas wie Jython + XMLBuilder + Templates um Testdaten für XML Applikationen zu erstellen. Ich brauche die Templates um die Testdaten gegen Interface Changes zu immunisieren.
Hi Mark!

Ich weiß nicht was XMLBuilder ist, aber vielleicht hilft dir folgende Herangehensweise:
Lese mit "ElementTree" oder mit pythoneigenen Mitteln wie z.B. MiniDOM deine XML-Daten aus und befülle damit ein mit SimpleTAL erstelltes Template.

Wie einfach das Auslesen der XML-Dateien gehen kann, zeigt blackbird in diesem Thread auf.

Und hier noch ein paar Beispiele:
http://www.python-forum.de/viewtopic.ph ... =simpletal
http://www.python-forum.de/viewtopic.ph ... =simpletal

Das ist aber nur eine Möglichkeit und setzt auch vorraus, dass ich dein Anliegen richtig verstanden habe. Es gibt natürlich noch viele andere.

mfg
Gerold
:-)

das mache ich - danke!

Verfasst: Sonntag 22. Januar 2006, 10:42
von Mark Fink
modelnine hat geschrieben:Schon mal ElementTree angeguckt? Bietet eigentlich relativ gute Interfaces um programmatisch XML zu erstellen. Und das Template besteht dann aus einer Python-Funktion die Du mit Argumenten aufrufst, und die Dir einen Baum zurückgibt.

So würde ich es machen...

--- Heiko.
Vielen Dank für den Tipp! ElementTree sehe ich mir sofort an. Wäre super wenn ich etwas bestehendes nutzen könnte...
Viele Grüße,
Mark

ElementTree

Verfasst: Sonntag 22. Januar 2006, 19:04
von Mark Fink
modelnine hat geschrieben:Schon mal ElementTree angeguckt? Bietet eigentlich relativ gute Interfaces um programmatisch XML zu erstellen. Und das Template besteht dann aus einer Python-Funktion die Du mit Argumenten aufrufst, und die Dir einen Baum zurückgibt.

So würde ich es machen...

--- Heiko.
ich habe mir elementTree mal genauer angeschaut (zumindest die Doku und einige Artikel). Ich verstehe elementTree als XMLBuilder mit dem man wunderbar XML Markup erzeugen kann. Was mir fehlt ist ein Template Mechnismus mit dem ich es schaffe Struktur und Inhalt zu trennen. z.B.:

XMLBuilder Markup (leichtgewichtig, effizient):
{"person": {"last": "flintstone", "first": "fred"}}

Template (in irgendeiner Form, leider bin ich mir noch nicht sicher wie soetwas aussehen sollte):
person.lastname=>person.last

Ergebniss wäre dann:

Code: Alles auswählen

<?xml version='1.0' encoding='utf-8'?>
<person>
  <lastname>flintstone</lastname>
  <first>fred</first>
</person>
Vermutlich ist die Forderung nach der Trennung von Inhalt und Struktur gar keine so ungewöhnliche Anforderung. Daher gibt es etwas derartiges bestimmt schon. XSLT ist mir allerdings zu schwergewichtig. Irgendeine Idee wie soetwas zu bewerkstelligen wäre

Edit by Gerold -- Code-Tags gesetzt.

Re: ElementTree

Verfasst: Sonntag 22. Januar 2006, 20:12
von gerold
Mark Fink hat geschrieben:Ergebniss wäre dann:

Code: Alles auswählen

<?xml version='1.0' encoding='utf-8'?>
<person>
  <lastname>flintstone</lastname>
  <first>fred</first>
</person>
Hi Mark!

Ich habe dich anscheinend wirklich falsch verstanden. Du willst nichts anderes als reines XML erstellen. Ist das richtig? Wenn dein XML nicht komplizierter als oben angegeben wird, dann frage ich mich, wozu du überhaupt ein Templating-System brauchst.

Code: Alles auswählen

xml = \
"""<?xml version='1.0' encoding='utf-8'?>
<personen>
"""

person_template = \
"""  <person>
    <lastname>%(lastname)s</lastname>
    <first>%(first)s</first>
  </person>
"""

personen = [
    {"lastname": "Penz1", "first": "Gerold1"},
    {"lastname": "Penz2", "first": "Gerold2"},
    {"lastname": "Penz3", "first": "Gerold3"},
]

for person in personen:
    xml += person_template % person
xml += "</personen>\n"
print xml
Ergebnis:

Code: Alles auswählen

<?xml version='1.0' encoding='utf-8'?>
<personen>
  <person>
    <lastname>Penz1</lastname>
    <first>Gerold1</first>
  </person>
  <person>
    <lastname>Penz2</lastname>
    <first>Gerold2</first>
  </person>
  <person>
    <lastname>Penz3</lastname>
    <first>Gerold3</first>
  </person>
</personen>
mfg
Gerold
:-)

Verfasst: Sonntag 22. Januar 2006, 20:35
von gerold
Und hier noch ein Beispiel mit SimpleTAL:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-

from simpletal import simpleTAL, simpleTALES

template = \
"""<?xml version='1.0' encoding='utf-8'?>
<personen><div tal:repeat="person personen" tal:omit-tag="">
  <person tal:attributes="vorname person/first; 
                          nachname person/lastname"
  /></div>
</personen>
"""

personen = [
    {"lastname": "Penz1", "first": "Gerold1"},
    {"lastname": "Penz2", "first": "Gerold2"},
    {"lastname": "Penz3", "first": "Gerold3"},
]

context = simpleTALES.Context(allowPythonPath=True)
context.addGlobal("personen", personen)

template = simpleTAL.compileXMLTemplate(template)
template.expand(context, sys.stdout)
Das Ergebnis sieht so aus:

Code: Alles auswählen

<?xml version="1.0" encoding="iso-8859-1"?>
<personen>
  <person vorname="Gerold1" nachname="Penz1" />
  <person vorname="Gerold2" nachname="Penz2" />
  <person vorname="Gerold3" nachname="Penz3" />
</personen>
mfg
Gerold
:-)

Verfasst: Montag 23. Januar 2006, 19:12
von Mark Fink
Hallo Gerold,

vielen Dank für Deine Hilfe. Leider hat TAL und SimpleTAL nicht den richtigen Ansatz für mein Problem. Ich habe oben versucht das Problem zu vereinfachen, offenbar ist es etwas zu einfach geraten (ich habe es unten nochmal nachgearbeitet). Sorry für das Missverständniss. SimpleTAL verarbeitet die Daten in einer Listendarstellung (flach). Ich möchte jedoch strukturierte Daten verarbeiten (am liebsten in der im Beispiel verwendeten Pseudo-XML Darstellung). Wichtig ist dabei folgendes:
Trennung von Struktur und Inhalt mit Hilfe eines Template Mechnismus.

Beispiel:

Code: Alles auswählen

XMLBuilder Markup (leichtgewichtig, effizient): 
{"person": {"last": "flintstone", "first": "fred", 
                  "address": {"street": "my way", "housenumber": "66", 
                   "city": "my town", "zip": "12345"}} }
Template (in irgendeiner Form, leider bin ich mir noch nicht sicher wie soetwas aussehen sollte):
person.lastname=>person.last
Natürlich sollen auch aufwändigere Transformationen darstellbar sein

Ergebniss wäre dann:

Code: Alles auswählen

<?xml version='1.0' encoding='utf-8'?>
<person>
  <lastname>flintstone</lastname>
  <first>fred</first>
  <address>
    <street>...</street>
    ...
  </address>
</person> 

Vermutlich ist die Forderung nach der Trennung von Inhalt und Struktur gar keine so ungewöhnliche Anforderung. Daher gibt es etwas derartiges bestimmt schon. XSLT ist mir allerdings zu schwergewichtig. Irgendeine Idee wie soetwas zu bewerkstelligen wäre? Zur Not codiere ich das auch selbst. Mir fehlt für das Templating noch eine gute Idee. Wahrscheinlich wird muss es auf soetwas wie XPATH - Ausdrücke für geschachtelte Listen/Dictionaries rauslaufen.
Mit dieser ganzen Geschichte kann ich dann Daten und Struktur getrennt ändern. Das bedeutet, bei einer Änderung der Struktur ändere ich nur da s Template und nicht die Daten. Daher sind solche Änderungen schnell und effizient durchzuführen. Im Content - Bereich gibt es soetwas schon längst. XSLT gibt es ja auch schon, ist mir jedoch zu schwerfällig.

Edit by Gerold: Code-Tags gesetzt.

Verfasst: Montag 23. Januar 2006, 20:46
von gerold
Mark Fink hat geschrieben:Vermutlich ist die Forderung nach der Trennung von Inhalt und Struktur gar keine so ungewöhnliche Anforderung.
Hi Mark!

Ich denke doch. XML stellt Daten **UND** Struktur dar. Dafür ist es gedacht. Wie auch immer. Hier habe ich noch ein Beispiel für dich. Solltest du aber nicht nur ein Dictionary mit Strings sondern auch Listen oder Tupel umsetzen wollen, dann empfehle ich dir wirklich darüber nachzudenken, ob du dich nicht doch ein wenig in *ElementTree*, *dom*, *minidom* und *sax* einlesen möchtest. :hint:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-

import types
from xml.dom import minidom


#----------------------------------------------------------------------
def dict2xml(mydict):
    """
    Läuft das Dictionary rekursiv durch und gibt einen XML-Teilstring zurück
    """
    
    s = ""
    
    for i, key in enumerate(mydict):
        if i == 0:
            keystring = key
        if isinstance(mydict[key], types.DictType):
            s += "<%s>%s</%s>" % (
                key, 
                dict2xml(mydict[key]), 
                key
            )
        else:
            s += "<%s>%s</%s>" % (
                key, 
                mydict[key], 
                key
            )
            
    return s


#----------------------------------------------------------------------
def main():
    
    d = {
        "person": {
            "last": "flintstone", 
            "first": "fred",
            "address": {
                "street": "my way", 
                "housenumber": "66",
                "city": {
                    "name": "my town", 
                    "zip": "12345"
                }
            }
        }
    }
    
    # XML generieren
    s = dict2xml(d)
    
    # Formatieren und ausgeben
    dom = minidom.parseString(s)
    print dom.toprettyxml("  ")
    

#----------------------------------------------------------------------
if __name__ == "__main__":
    main()

Code: Alles auswählen

<?xml version="1.0" ?>
<person>
  <address>
    <city>
      <name>
        my town
      </name>
      <zip>
        12345
      </zip>
    </city>
    <street>
      my way
    </street>
    <housenumber>
      66
    </housenumber>
  </address>
  <last>
    flintstone
  </last>
  <first>
    fred
  </first>
</person>
mfg
Gerold
:-)

Verfasst: Montag 23. Januar 2006, 21:16
von gerold

Verfasst: Montag 23. Januar 2006, 23:37
von Mark Fink
Hmmm, das kenne ich alles schon. Die anderen 20 gängigen Python-XML-Frameworks habe ich mir auch schon angeschaut. Leider hat keines den oben beschriebenen Template Mechanismus bzw. Transformationen. Ich habe noch an einen XML Guru geschrieben und dehne meine Suche jetzt noch weiter aus. Falls ich etwas brauchbares finde melde ich mich wieder.
Vielen herzlichen Dank für eure Hilfe.
Grüße,
Mark Fink
http://www.mark-fink.de

Verfasst: Dienstag 24. Januar 2006, 07:19
von jens
Mal so allgemein gesprochen... Ich denke nicht, das du für flexible Daten überhaupt ein Template nutzten kannst. Denn das würde IMHO nur bei fester Datenstruktur mit variablen längen gehen.
Beispiel Adressen: Man muß schon vorher wissen, ob eine Strasse eine Hausnummer hat oder nicht. Fehlt diese im Template, wie soll sie eingefügt werden??? Somit eignen sich Templates für Dynamische Daten nicht, da kommst du um minidom und Co. nicht herrum.
Hast du aber immer strikt die selbe Datenstruktur, müßte das mit simpleTAL Prima gehen...

Was für Daten hast du?