xml auslesen,Gui eintragen,Gui ändern,lesen,xml schreiben

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
Pü-Ton
User
Beiträge: 67
Registriert: Donnerstag 8. Mai 2008, 07:52

Hi Leute,

ich bin mal wieder am Ende meines Wissens...

Aus einem XML werden Daten ausgelesen, diese dann in verschiedene Entry`s und Labels geschrieben.

Wenn ich jetzt das XML verändere und dieses abspeicher nd dann auf einen Reload-Button klicke, soll das veränderte XML neu geladen werden... Also im Code wird die ReadXML() einfach nochmal aufgerufen !!!

Alles was aber passiert: Die Gui zuckt kurz, jedoch seh ich nach wie vor den Inhalt, der zuerst ausgelesenen XML, also ohne die Veränderungen.

Muss man das eingelesene XML zuerst löschen oder aus dem Speicher entfernen oder sowas, damit dann das veränderte XML angezeigt werden kann???

Wie macht man sowas???

Danke
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Pü-Ton hat geschrieben:Wie macht man sowas???
Ohne ein Stück brauchbaren Code wird es schwierig sein, dir bei der Lösung des Problems zu helfen.

Da es hier offenbar nur um die Anzeige geht, wäre der Thread im Bereich "Tkinter" auch besser aufgehoben.
Pü-Ton
User
Beiträge: 67
Registriert: Donnerstag 8. Mai 2008, 07:52

Also hier ist mal ein CodeTeil:

Code: Alles auswählen

    
    eingabeInput = eingabe.get()
    testxml = parse(eingabeInput)
    Readcfg()
    
    
    def Readcfg():
        for elements in testxml.getElementsByTagName('User'):
            for elemen in elements.getElementsByTagName("Case"):
                for elem in elemen.getElementsByTagName("Name"):
                    if elem.hasChildNodes():
                        inhalt = elem.childNodes[0].nodeValue
                        print inhalt
                    else:
                        print "has no ChildNodes !!! "

    def clearOldChilds():
        for elements in testxml.getElementsByTagName('User'):
            for elemen in elements.getElementsByTagName("Case"):
                for elem in elemen.getElementsByTagName("Name"):
                    if elem.hasChildNodes():
                        print "hasChildNodes"
    #                    elem.removeChild(elem.firstChild)
    #                    elem.unlink()
        Readcfg()
Kann sein, dass das jetzt nicht so richtig nachvollziehbar ist...


Ablauf:
Bei Programmstart wird also die Readcfg() aufgerufen, die dann das XML ausliest und mir über "Inhalt" auch anzeigt... (Innerhalb der Funktion werded dann noch andere Funktionen aufgerufen, die mir das auch in die GUI schreiben).

Wird jetzt der Reloadbutton gedrückt, wird also die clearOldChilds() aufgerufen, die das eingelesene löschen und dann wieder die Readcfg(), zum erneuten einlesen, aufrufen soll.

Jetzt ists nur so, dass nach dem Löschen die Value-Fehlermeldung kommt:

Code: Alles auswählen

IndexError: list index out of range
-bezogen auf elem.childNodes[0].nodeValue aus Inhalt

Ich hoffe, dass das ein wenig hilft...
Pü-Ton
User
Beiträge: 67
Registriert: Donnerstag 8. Mai 2008, 07:52

Oha,
ich hab gerade rausgefunden, dass ich das

Code: Alles auswählen

    eingabeInput = eingabe.get()
    testxml = parse(eingabeInput)
innerhalb der Funktion Readcfg() drinhaben muss, damit er es neu einliest.
Also neu einlesen geht.

Jedoch wird das zuvor eingelesene überschrieben, ohne es vorher zu löschen...

So gesehen bleibt meine ursprüngliche Frage:

--> Wie lösche ich eingelesene XML Daten, damit sie fehlerfrei "überschrieben" werden können ???



Übrigens verwende ich DOM / MININDOM und will da auch nix mit SAX/ELEMENTTREE o.ä. machen, wenn es möglich ist...
BlackJack

@Pü-Ton: Du behauptest `Readcfg()` würde das XML einlesen. Tut es aber nicht.
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

Hi,

sieht so aus, als würde elem.hasChildNodes() nicht mit elem.childNodes zu harmonisieren. Gibt doch mal vor dem Indexzugriff die Liste selbst aus, also

Code: Alles auswählen

print elem.childNodes, len(elem.childNodes)
Um sicherzugehen verwende statt

Code: Alles auswählen

if elem.hasChildNodes():
lieber

Code: Alles auswählen

if elem.childNodes:
, ist auch kürzer.

Gruß,
Michael
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Pü-Ton hat geschrieben:Jedoch wird das zuvor eingelesene überschrieben, ohne es vorher zu löschen...
:shock: Wenn es überschrieben wird, dann ist das, was vorher das stand doch zwangsläufig gelöscht.

Du willst doch wohl nicht behaupten, dass so eine Art Mischung aus beiden Texten entsteht, bei der z.B. der neue Text nur die Leerzeichen des alten mit ergänzenen Buchstaben füllt ...

Aber falls es hilft:

Code: Alles auswählen

import Tkinter as tk

root = tk.Tk()
entry = tk.Entry(root)
entry.insert("0","Please delete me!")
button = tk.Button(root,text="Delete",command=lambda:entry.delete("0","end"))
entry.pack()
button.pack()
root.mainloop()
Pü-Ton
User
Beiträge: 67
Registriert: Donnerstag 8. Mai 2008, 07:52

@BlackJack:
Also in der Variante, die ich hier gepostet hab, liest es mir die Inhalte des Tags "Name" aus und schreibt sie mir schön in das Ausgabefenster meines Editors. Oder was genau meinst Du?

@ Michael:

Code: Alles auswählen

print elem.childNodes, len(elem.childNodes)
bringt:

Code: Alles auswählen

Eintrag 1
[<DOM Text node "Eintr...">] 1
Eintrag 2
[<DOM Text node "Eintr...">] 1
Eintrag 3
[<DOM Text node "Eintr...">] 1
Eintrag 4
[<DOM Text node "Eintr...">] 1
Wobei "Eintrag X" der Inhalt aus den "Name"-Tags ist !!!
Pü-Ton
User
Beiträge: 67
Registriert: Donnerstag 8. Mai 2008, 07:52

@numerix:
Doch, so sieht es zumindest aus...

Ein kurzes Wort wird über ein längeres geschrieben. Wenn das lange Wort zuerst ausgegeben wurde, wird nach dem Reload das Kurze Wort über das lange gesetzt und man sieht das Kurze Wort und den Rest vom langen Wort !!!
BlackJack

@Pü-Ton: Ich meinte, dass was ich geschrieben habe. Und was Du in Deinem Beitrag direkt davor ja auch selbst gemerkt hast.

Wie gibst Du denn die Daten aus? Du erzeugst nicht zufällig neue Labels, die dann alle über einander liegen, oder etwas in der Art? Wenn Du den Text wirklich ersetzt, sollte das alte auch automatisch entfernt werden.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

BlackJack hat geschrieben:Wie gibst Du denn die Daten aus? Du erzeugst nicht zufällig neue Labels, die dann alle über einander liegen, oder etwas in der Art? Wenn Du den Text wirklich ersetzt, sollte das alte auch automatisch entfernt werden.
Das dürfte in der Tat die einzige Erklärung sein, denn weder mit Labels noch Entrys lässt sich das von dir (Pü-Ton) beschriebene Verhalten realisieren.

Ich verweise nochmal auf mein erstes Posting dazu: Das Problem ist doch die Anzeige der Daten. Warum zeigst du dann nicht den entsprechenden Code, sondern Teile, die damit gar nichts zu tun haben?
Pü-Ton
User
Beiträge: 67
Registriert: Donnerstag 8. Mai 2008, 07:52

Oh jeeeee,

jetzt fällt es mir wie Schuppen von den Augen...

Ich habe für die Anzeige in der GUI ein Canvas erstellt, in das für jedes Element in der XML mittels create_window ein Label, bzw Entry erstellt wird.

Diese werden jetzt natürlich nicht gelöscht sondern die neuen kreierten windows werden einfach draufgesetzt und dementsprechend angezeigt...

Ihr hattet natürlich recht...

Danke, für die Wegweiser...
Ich werd das jetzt nochmal anders machen... Also den Aufbau der GUI.

Danke
Pü-Ton
User
Beiträge: 67
Registriert: Donnerstag 8. Mai 2008, 07:52

So, nachdem ich nunmein Prog soweit abgeändert habe, dass bei einem Reload erstmal die bestehenden Canvas.create_window`s gelöscht und anschliessend erst wieder "neu" erstellt werden, kämpfe ich mit einem Data-Entry, dass 2 Werte einliesst und in ein XML-schreiben soll.

Die Data-Entries sind Messageboxen, mit " tkSimpleDialog.askstring " erstellt. In readVariable_name steht jetzt der eingetragene Variablename und in readValue der Wert des Values.
Diese beiden eingetragenen Werte sollen nun in eine vorhandene XML-Strucjtur eingefügt werden.



Das XML-File:

Code: Alles auswählen

<?xml version="1.0" ?>
<environment>
	<Info>
		<Name>Ich bin`s</Name>
		<Version>die dritte</Version>
		<Date>gestern</Date>
	</Info>
	<Variables>
		<Tag>
			<Name>Essen</Name>
			<Value>Obst</Value>
		</Tag>
	</Variables>
</environment>

Unter "Variables" soll nun ein neuer Tag entstehen, der eben "Tag" heisst und dieser "Name" und "Value" enthält, die wiederum die Eingaben aus "readVariable_name" und "readValue" enthalten.

hier der Code:

Code: Alles auswählen

    def addvar():
        readVariable_name = tkSimpleDialog.askstring("Add new Variable", "Variable name")
        if readVariable_name:
            readValue = tkSimpleDialog.askstring("Add new Value", "Value")
            #print readVariable_name
            #print readValue



            varsRoot = xml.getElementsByTagName('Variables')[0]
            
            variableNode = xml.createElement("Tag")

            nameNode = xml.createElement("Name")
            nameNodeText = xml.createTextNode(readVariable_name)

            valueNode = xml.createElement("Value")
            valueNodeText = xml.createTextNode(readValue)



            variableNode.appendChild(nameNode)
            variableNode.appendChild(valueNode)
            varsRoot.appendChild(variableNode)

            f = file(C:\Python25\xml, "w")
            f.write(xml.toxml())
            f.close

Code: Alles auswählen

<?xml version="1.0" ?><environment>
		<Info>
		<Name>Ich bin`s</Name>
		<Version>die dritte</Version>
		<Date>gestern</Date>
	</Info>
	<Variables>
		<Tag>
			<Name>Essen</Name>
			<Value>Obst</Value>
		</Tag>
	<Tag><Name/><Value/></Tag></Variables>

...
also a) verschoben und ohne die richtige Tag-Formatierung <> -- </> und b) klappt`s nicht so wie ich es gerne hätte mit der Formatierung also der Darstellung und c) fehlen die Einträge aus dem Data-Entry komplett...

Sieht jemand wo sich die Fehler eingeschlichen haben und kann mir helfen?

Wäre super,
danke
Pü-Ton
User
Beiträge: 67
Registriert: Donnerstag 8. Mai 2008, 07:52

hmmm, ich hab mir jetzt mal ohne das speichern in das XML-File den Inkalt der Knoten "Name" und "Value" anzeigen lassen und da stehen die Eingaben drin:

Code: Alles auswählen

        for elements in testxml.getElementsByTagName('Variables'):
            for elemen in elements.getElementsByTagName("Tag"):

                for elem in elemen.getElementsByTagName("Name"):
                    if elem.hasChildNodes():
                        print elem.childNodes[0].nodeValue

                for elem in elemen.getElementsByTagName("Value"):
                    if elem.hasChildNodes():
                        print elem.childNodes[0].nodeValue
Ausgabe:

Code: Alles auswählen

uuu
aaa
Essen
Obst
Wobei uuu und aaa meine Eingaben waren.
Soweit gehts also...

Dann stimmt was mit dem speicher-Befehl nicht, oder???
Gibts da alternativen ???

Übrigens:
Alles mit Tkinter und Dom / Minidom
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

Hi Pü-Ton!
Pü-Ton hat geschrieben:@ Michael:

Code: Alles auswählen

print elem.childNodes, len(elem.childNodes)
bringt:

Code: Alles auswählen

Eintrag 1
[<DOM Text node "Eintr...">] 1
Eintrag 2
[<DOM Text node "Eintr...">] 1
Eintrag 3
[<DOM Text node "Eintr...">] 1
Eintrag 4
[<DOM Text node "Eintr...">] 1
Merkwürdigerweise tritt keine Exception mehr auf!! Also entweder hast Du meine Zeile mit dem Ausgabecode nicht vor Deinem Elementzugriff in Zeile 13 eingefügt, oder Du hast den Code anderweitig korrigiert.
Z.B. durch das Ersetzen der Bedingung in Zeile 12 durch "if elem.childNodes". Die beiden vorgeschlagenen Änderungen darfst Du natürlich nicht gleichzeitig machen! Ich meinte, dass Du den Ausgabecode in Deinen Originalcode mit dem elem.hasChildNodes() einsetzt, um kurz vor der Ausnahme den aktuellen Wert auszugeben.

Michel
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Pü-Ton
User
Beiträge: 67
Registriert: Donnerstag 8. Mai 2008, 07:52

Hallo Michael,

halt halt, es geht gar nicht mehr direkt um das zu Anfang dieses Threads gepostete Problem.
Die Geschichte mit dem Reload hab ich gelöst.

Es geht jetzt nur noch um das wegspeichern der Data-Entry Einträge in das vorhandene XML-File, mit der gleichen Formatierung (also eigentlich ist es ja ein Einfügen) wie der bestehende Rest...


Wenn ich aber Deine nochmal Vorgeschlagene Zeile einfüge:

Ausgabe:

Code: Alles auswählen

ggg
zzz
[<DOM Text node "Essen...">] 1
[<DOM Text node "Obst...">] 1
Pü-Ton
User
Beiträge: 67
Registriert: Donnerstag 8. Mai 2008, 07:52

Hab es rausgefunden:

Code: Alles auswählen

            variableNode.appendChild(nameNode)
            [color=red]nameNode.appendChild(nameNodeText)[/color]
            variableNode.appendChild(valueNode)
            [color=red]valueNode.appendChild(valNodeText)[/color]
            varsRoot.appendChild(variableNode)
statt:

Code: Alles auswählen

            variableNode.appendChild(nameNode)
            variableNode.appendChild(valueNode)
            varsRoot.appendChild(variableNode)

oft liegt das einfache zu weit weg...

Allerdings ist die Formatierung nicht eingehalten, wenn ich es mit

Code: Alles auswählen

            f = file(C:\Python25\xml, "w")
            f.write(xml.toxml())
            f.close
speichere.

LG :D
BlackJack

Wenn Du keine Formatierung in das XML schreibst gibt's halt auch keine. Allerdings speichert der gezeigte Quelltext gar nichts, sondern steigt mit einem `SyntaxError` aus.

Code: Alles auswählen

In [85]: file(C:\Python25\xml, "w")
------------------------------------------------------------
   File "<ipython console>", line 1
     file(C:\Python25\xml, "w")
           ^
<type 'exceptions.SyntaxError'>: invalid syntax
Pü-Ton
User
Beiträge: 67
Registriert: Donnerstag 8. Mai 2008, 07:52

ha ja, wenn ich vergesse den Pfad in Anführungsstricht zu setzen...

Kannst Du mir dann bitte zeigen, wie man in meinem Beispiel richtig formatiert?

Code: Alles auswählen

<?xml version="1.0" ?>
<environment>
    <Info>
        <Name>Ich bin`s</Name>
        <Version>die dritte</Version>
        <Date>gestern</Date>
    </Info>
    <Variables>
        <Tag>
            <Name>Essen</Name>
            <Value>Obst</Value>
        </Tag>
        <Tag>
            <Name>ooo</Name>
            <Value>aaa</Value>
        </Tag>
    </Variables>
</environment>
statt:

Code: Alles auswählen

<?xml version="1.0" ?><environment>
        <Info>
        <Name>Ich bin`s</Name>
        <Version>die dritte</Version>
        <Date>gestern</Date>
    </Info>
    <Variables>
        <Tag>
            <Name>Essen</Name>
            <Value>Obst</Value>
        </Tag>
    <Tag><Name>ooo</Name><Value>aaa</Value></Tag></Variables>
Antworten