Problem mit lxml

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

@blubber: Du musst sauberer zwischen Python und XPath unterscheiden. Das ``[0]`` ist nicht im XPath-Ausdruck sondern im Python-Quelltext. Bei XPath-Ausdrücken, die Knotenmengen beschreiben, liefert die `xpath()`-Methode immer eine Liste zurück und auf die bezieht sich der Indexzugriff.

Ebenso kannst Du in XPath-Ausdrücken nicht einfach Python-Namen verwenden und erwarten, das die da auf magische Weise bekannt sind.

Zum ersten Problem: Dann schränk doch einfach den Datenknoten noch mit der Bedingung zum Nachnamen ein.

Zum zweiten Problem: Vergiss was Leonidas dazu geschrieben hat, das ist nämlich nicht viel besser als Variablen per Zeichenformatierung in SQL ein zu fügen. :-)

Und dann lese ich Dir hier mal die Doku vor:
http://codespeak.net/lxml/xpathxslt.html hat geschrieben:The xpath() method has support for XPath variables:

Code: Alles auswählen

>>> expr = "//*[local-name() = $name]"

>>> print(root.xpath(expr, name = "foo")[0].tag)
foo

>>> print(root.xpath(expr, name = "bar")[0].tag)
bar

>>> print(root.xpath("$text", text = "Hello World!"))
Hello World!
blubber
User
Beiträge: 123
Registriert: Montag 19. März 2007, 09:08

Zum ersten Problem: Ok, mein Fehler. Selbstverständlich habe ich das ausprobiert. Mein Fehler war einfach, dass ich mit meiner Ziel-XML rumprobiert habe, und die ist relativ groß/komplex. Daher hat es funktioniert und ich habe es einfach nur übersehen :(

Zum zweiten Problem: Ich kenn den Ausschnitt der Docu, hab sie - wie erwähnt - wirklich durchgelesen, nur hilft mir das irgendwie nicht weiter :cry:
Hab rumprobiert mit

Code: Alles auswählen

Zeitpunkt = "heute"
.../Gesamt[@zeit=$Zeitpunkt]/...
und lauter so Sachen, aber mir wird aus dem Codebeispiel der Doku nicht ersichtlich, wie ich das jetzt machen muss.
Bin glaub echt zu blöd für sowas :cry:
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Funktioniert hier problemlos:

Code: Alles auswählen

root.xpath('/Gesamt[@zeit=$zeitpunkt]/test[@name="Test1"]/datensatz[@ID="4"]/daten[@Nachname=$nachname]', zeitpunkt="heute", nachname="Stachelmann")[0].attrib['Vorname'] = 'Manni'
Nehme ich richtig an dass die XPath Variablen richtig escaped werden, bevor sie eingefügt werden? Dann wäre das tatsächlich sinnvoller als String-Formatting (was in meinem Beispiel im übrigen sowieso nicht funktioniert hätte). Soweit ich das sehe, ja, aber die Dokumentation dazu ist etwas dünn.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
blubber
User
Beiträge: 123
Registriert: Montag 19. März 2007, 09:08

ok, so funktioniert das bei mir jetzt auch.
Danke :oops: :(
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

blubber hat geschrieben: Hab rumprobiert mit

Code: Alles auswählen

Zeitpunkt = "heute"
.../Gesamt[@zeit=$Zeitpunkt]/...
und lauter so Sachen, aber mir wird aus dem Codebeispiel der Doku nicht ersichtlich, wie ich das jetzt machen muss.
Und warum hast du es nicht mit ("../Gesamt[@zeit=$Zeitpunkt]/.../", Zeitpunt = "jetze")

ausprobiert? Immerhin fliegt das seit zahlreichen Posts im Thread rum ;)
blubber
User
Beiträge: 123
Registriert: Montag 19. März 2007, 09:08

Ja es sieht vielleicht so aus, als probier ich nix, aber ich probier so viel herum, dass ich schon garnichtmehr weis, was ich alles probiert und nicht probiert habe. Genau so mit dem Problem1 von eben, was eigentlich funktioniert hatte und ich es garnicht mehr gemerkt habe.
Also danke nochmal für die Geduld. Mein Problem konnte ich nun lösen.
Nurnoch rein aus Interesse und nicht mehr notwendig:
(Falls ich nerve, kann das Thema hier auch geschlossen werden)

Wäre es, falls nötig, denn auch möglich, den "Durchlauf" der XML zu kombinieren? Als Beispiel wieder der Ausgangscode:

Code: Alles auswählen

from lxml import etree as ET 

root = ET.fromstring("""<Gesamt zeit = "heute"> 
    <test name = "Test1"> 
       <datensatz ID = "1"> 
           <daten 
                  Vorname="otto" 
                  Nachname = "waldmann"/> 
       </datensatz>
       <datensatz ID = "4"> 
           <daten 
                  Vorname="hans" 
                  Nachname = "stachelmann"/> 
           <daten 
                  Vorname="hans" 
                  Nachname = "mustermann"/> 
       </datensatz>        
    </test> 
    <test name = "Test2"> 
    </test> 
    <test name = "Test3"> 
    </test> 
</Gesamt> """) 

root.xpath('/Gesamt[@zeit="heute"]/test[@name="Test1"]/datensatz[@ID="4"]/daten[@Nachname="mustermann"]')[0].attrib['Vorname'] = 'Manni'
print ET.tostring(root)
Wenn man zum Beispiel möchte, dass man die @zeit konkret angibt, @test konkret angibt, nun aber datensatz nicht konkret (über @ID=4) sondern als Nummer angibt.....also zweiter Datensatz oder so.
Im Gesamten (Pseudo) in der Art:

Code: Alles auswählen

root.xpath('/Gesamt[@zeit="heute"]/test[@name="Test1"]/datensatz[Nr2]/daten[@Nachname="mustermann"]')[0].attrib['Vorname'] = 'Manni'
Wäre das '''datensatz[Nr2]''' irgendwie möglich?
Wie gesagt, ist für mein Problem nicht mehr notwendig, wäre nurnoch Interesse.

Danke an alle.

Gruß
BlackJack

@blubber: Ist möglich: '.../datensatz[2]/...'.
Antworten