XML Element Typ als Datenspeicher missbrauchen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
AllesMeins
User
Beiträge: 63
Registriert: Donnerstag 20. November 2003, 13:45
Wohnort: Frankfurt/M.

Hi,

folgende Frage. Ich bastele zur Zeit an einer kleinen Anwendung, die XMLs verarbeitet (etree/lxml). Nun kommt mir die von etree.parse() angelegte Datenstruktur sehr entgegen, sprich sie enthält die Daten genau so wie ich sie zum verarbeiten brauche. Nun möchte ich aber gerne zu einzelnen Elementen Zusatzinformationen (von unterschiedlichen Datentypen) speichern, die ich später auch wieder entsprechend zuordnen können muss. Also ein stark vereinfachtes Beispiel, das aber den ungefähren Sinn meiner Anfrage klar machen sollte

Code: Alles auswählen

<gruppe>
<mitglied>XYZ</mitglied>
<mitglied>ABC</mitglied>
<mitglied>UVW</mitglied>
</gruppe>
<gruppe>
<mitglied>123</mitglied>
...
Nun mache ich für jedes Mitglied irgend eine aufwendige Berechnung, fasse diese Berechnungen zusammen und muss die Ergebnisse nun so vorhalten das ich sie zu einem späteren Zeitpunkt wieder der entsprechenden Gruppe zuordnen kann.
Am schönsten wäre es daher für mich einfach das <gruppe>-Element irgendwie intern zu erweitern, um meine Daten direkt da rein speichern zu können (ich will also kein neues XML-Element/Attribut in den Baum einfügen - da die zu speichernden Daten nicht unbedingt Text sein müssen. Und soweit ich das sehe müssen Attribute ja Text sein). Dann hätte ich beim Arbeiten mit solch einem Element jederzeit die gewünschten Daten direkt zur Verfügung, ich muss mir keine Gedanken über die korrekte Zuordnung machen und könnte außerdem noch von den lxml-Funktionen profitieren, falls ich doch noch mal an die Unterelemente oder so ran muss.

Kann ich in Python Datentypen derart erweitern (das müsste natürlich so geschehen, das etree dann diese erweiterten auch verwendet, anlegen eines neuen, kopierten Datentyps bringt mir ja nichts)? Wenn ja, wie mache ich das? Wenn nein, wie sollte ich meine Daten ansonsten am besten speichern um sie sicher und einfach der jeweiligen Gruppe zuordnen zu können?
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ich muss gestehen, dass ich das nicht so unbedingt kapiere. Wieso kannst Du die Daten der Berechnung nicht unterhalb vom <gruppe>-Tag in einer eigenen Tag-Struktur ablegen?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
/me
User
Beiträge: 3556
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

AllesMeins hat geschrieben:Wenn nein, wie sollte ich meine Daten ansonsten am besten speichern um sie sicher und einfach der jeweiligen Gruppe zuordnen zu können?
Ich gehe jetzt mal davon aus, dass du hier nicht von einer Speicherung in der XML-Datei redest, sondern einem Hinzufügen von Daten in der vom Parser zur Verfügung gestellten Abstraktionsebene. Anders wäre deine Anfrage auch nicht plausibel.

Du wirst eine Gruppe anhand irgendeines Kriteriums eindeutig identifizieren können. Verwende dieses Kriterium als Schlüssel für ein Dictionary das die gewünschten Zusatzdaten vorhält.

Alternativ kannst du bestehende Verwaltungsobjekte auch einfach zur Laufzeit erweitern

Code: Alles auswählen

class Foo(object):
    pass

bar = Foo()
bar.baz = "Hello, world!"

print dir(bar)
BlackJack

@AllesMeins: Zumindest an `lxml.Element`-Objekte kann man keine eigenen Attribute hängen, das fällt also aus. Du könntest vielleicht von der Klasse eine eigene ableiten und dann einen `XMLParser` mit einem `TreeBuilder` als `target`-Argument erstellen, der selber wiederrum die abgeleitete `Element`-Klasse als `element_factory` bekommt.

Vielleicht ist es aber auch einfacher ein `dict` anzulegen, was Deine `<gruppe>`-Elemente auf die berechneten Werte abbildet.
AllesMeins
User
Beiträge: 63
Registriert: Donnerstag 20. November 2003, 13:45
Wohnort: Frankfurt/M.

Hmm, schade dass man das nicht einfach so erweitern kann. Das wäre wirklich praktisch. Also muss ich wohl an die dict-Lösung ran. Aber da habe ich immer noch probleme mit der Zuordnung. In der XML-Datei selber gibt es kein eindeutiges Kriterium, mit der ich ein Ergebniss einer Gruppe zuordnen kann. Jetzt könnte ich natürlich jeder Gruppe einfach ein Attribut hinzufügen, dort eine eindeutige ID reinschreiben und die als Schlüssel für das Dict verwenden. Damit käme ich dann gut an die Daten, allerdings müsste ich dann später die XML wieder bereinigen, um sie ausgeben zu können.
Kann ich das irgendwie umgehen? Die einzelnen Element-Objekte müssen ja Python-Intern bereits einen eindeutigen Identifier haben, oder? Komme ich da irgendwie ran? Und würde der sich als key für das dictionary eignen?
BlackJack

@AllesMeins: Du kannst die Elemente selbst als Schlüssel verwenden, denn die haben ja eine Identität und die wird per Default bei Vergleichen verwendet wenn eine Klasse da nichts überschreibt. Und das passiert AFAIK nicht. Ansonsten kannst Du die `id()`-Funktion verwenden um einen eindeutigen Schlüssel zu erzeugen.
AllesMeins
User
Beiträge: 63
Registriert: Donnerstag 20. November 2003, 13:45
Wohnort: Frankfurt/M.

BlackJack hat geschrieben:@AllesMeins: Du kannst die Elemente selbst als Schlüssel verwenden
Sowas geht? Das is ja krank. Da streubt sich irgendwie alles in mir, das zu machen. Aber danke an alle für die Hinweise/Hilfen - ich denke ich komme jetzt zurecht!
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

AllesMeins hat geschrieben:
BlackJack hat geschrieben:@AllesMeins: Du kannst die Elemente selbst als Schlüssel verwenden
Sowas geht? Das is ja krank. Da streubt sich irgendwie alles in mir, das zu machen.
Inwiefern? Jedes hashbare Objekt kann als Schlüssel verwendet werden.

Bei PyQt kommt z.B. so etwas in der Art vor:

Code: Alles auswählen

In [3]: dispatch = {
        int: "Integer",
        str: "String"
}

In [8]: value = 42

In [9]: dispatch[type(value)]
Out[9]: 'Integer'                                                                                                                                                     
                                                                                                                                                                      
In [10]: value = "Hallo Welt!"
                                                                                                                                                                      
In [11]: dispatch[type(value)]                                                                                                                                       
Out[11]: 'String'                                                                                                                                                     
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Antworten