Seite 1 von 1

letztes Objekt in einer XML finden

Verfasst: Mittwoch 31. Juli 2013, 12:10
von kruphi
Nach dem Ihr mir letztes mal schon so klasse geholfen habt, bräuchte ich noch einmal eure Hilfe!

In meinem XML Objekt muss ich die Jahrgänge an einer bestimmten Stelle finden. Diese stehen wie unten an einem Beispiel beschrieben immer in einem Tag. Bei jedem Jahrgang wird ein neuer Tag eingefügt. Ich musst immer den letzten finden. Es können halt mal einmal Jahrgangsdaten auftauchen, aber auch mal 3 oder 4 Einträge.

Code: Alles auswählen

<mitglied>
    <personen>...</personen>
    ......
    ......
    <jahrgangsliste>
              <Jahrgangsdaten>
              <klasse> 12 </klasse>
              </jahrgangsdaten>
    </jahrgangsliste>
</mitglied>
mein Funktionen sehen bislang wie folgt aus. Mein Ansatz ist mit der Funktion rueck() heraus zu finden ob es noch einen nächsten Wert gibt. Gibt es da nicht einen eleganteren Weg?
Vielleicht etwas mit x.getElementsByTagName(y)[l].lastChild.nodeValue oder ähnliches.

Code: Alles auswählen


def rueck(l,x,y):

    try:
        wert = x.getElementsByTagName(y)[l].firstChild.nodeValue 
        return True
    except:
        return False
def getIt(x,y): #Gibt das Element zurück 
    try:
        return x.getElementsByTagName(y)[0].firstChild.nodeValue
    except:
        return ""
    file = open("hash.txt", "r") # read mode
    h = pickle.load(file)

def getIt2(x,y): #Gibt zweite das Element zurück 
Vielen Dank jetzt schon mal an dieser Stelle!

Re: letztes Objekt in einer XML finden

Verfasst: Mittwoch 31. Juli 2013, 12:41
von BlackJack
@kruphi: Ich würde ja einfach `lxml.etree` und XPath verwenden.

Ansonsten könntest Du über alle Kindknoten vom <mitglied>-Knoten iterieren und immer wenn ein <jahrgangsliste>-Knoten kommt, den an einen Namen binden. Nach der Schleife ist dann der letzte <jahrgangsliste>-Knoten an diesen Namen gebunden.

Re: letztes Objekt in einer XML finden

Verfasst: Mittwoch 31. Juli 2013, 12:45
von Sirius3
@kruphi: Ich würde ja ElementTree aus der Standardbibliothek nehmen. Für jeden Mitglied-Knoten gibt Dir dann member.find('jahrgangsliste/jahrgansdaten')[-1] das letzte Tag zurück.

Re: letztes Objekt in einer XML finden

Verfasst: Mittwoch 31. Juli 2013, 14:01
von kruphi
es gibt doch eine Funktion mit dem getElementsByTagName(y)[l].lastChild.nodeValue die gibt mir allerdings nicht die richtigen Ergebnisse aus

Re: letztes Objekt in einer XML finden

Verfasst: Mittwoch 31. Juli 2013, 16:33
von BlackJack
@kruphi: Es gibt aber auch die ElementTree-API über das Modul aus der Standardbibliothek oder, etwas aufgebohrt, aus `lxml.etree`. Diesen DOM-Mist würde ich nur verwenden wenn man mich bedroht. ;-)

Re: letztes Objekt in einer XML finden

Verfasst: Donnerstag 1. August 2013, 08:44
von kruphi
Leider laufen die anderen Teile des Programms schon mit minidom und ich will jetzt nicht alles umstricken!

Ich habe jetzt eine Lösung gefunden die mir das letzt Element anzeigt.

Code: Alles auswählen

def rueck(l,x,y):
    try:
        wert = x.getElementsByTagName(y)[l].firstChild.nodeValue 
        return True
    except:
        return False
def getLast(x,y):
    wert=0
    l=0
    while rueck(l,x,y):
        wert=x.getElementsByTagName(y)[l].firstChild.nodeValue
        l = l+1
    return wert   
Das wäre mein Lösungsansatz!

Re: letztes Objekt in einer XML finden

Verfasst: Donnerstag 1. August 2013, 09:23
von BlackJack
@kruphi: Oh, mann. :roll: Umständlicher geht es wohl kaum. Mach Dir mal klar wie viel unnötige Arbeit hier verrichtet wird. Wie oft immer und immer wieder der gleiche XML-Unterbaum nach den immer gleichen Knoten abgesucht wird, und wie oft eine Liste mit diesen Knoten erstellt, *einer* davon genommen, und alles wieder verworfen wird. Obwohl die Liste jedes mal den *gleichen Inhalt* hat.

Ausserdem sind die Namen sauschlecht. `x` und `y` kann man ja für Koordinaten verwenden, aber doch nicht für XML-Knoten und Tagnamen. Wenn man da `node` und `tag_name` verwendet, wird es gleich *viel* verständlicher. Bei `l` besteht zusätzlich zu dem nichtssagenden Namen bei vielen Schriftarten noch eine leichte Verwechslungsgefahr mit `I` und `1`.

Ein nacktes ``except`` ist ebenfalls eine schlechte Idee. Damit werden *alle* Ausnahmen behandelt, auch welche mit denen man gar nicht rechnet, und die man auf diese Weise niemals zu Gesicht bekommt. Man sollte dort immer die konkret erwartete(n) Ausnahme(n) angeben, oder dafür sorgen, dass nicht erwartete Ausnahmen nicht einfach „verschluckt” werden. Die `rueck()`-Funktion erscheint mir auch etwas zu spezialisiert und kurz, als dass es sich lohnen würde die als einzelne Funktion zu haben. Das hätte man auch gleich in die andere Funktion integrieren können.

Ungetestet:

Code: Alles auswählen

def get_last(node, tag_name, default=0):
    result = default
    for element in node.getElementsByTagName(tag_name):
        try:
            result = int(element.firstChild.nodeValue)
        except IndexError:
            pass    # Intentionally ignored.
    return result

Re: letztes Objekt in einer XML finden

Verfasst: Donnerstag 1. August 2013, 09:32
von kruphi
@BlackJack: Danke für deine Kritik/Verbesserungsvorschläge, nur so werde meine Programme nicht nur lauffähig sondern auch effizient!
Wie gesagt ich bin erst seit 3 Woche dabei und freue mich über solche Vorschläge.
Ich habe diese soeben in mein Code eingebunden und alles läuft.

Besten Dank hierfür !