Seite 1 von 1

XML-Tag-Vergleich

Verfasst: Dienstag 25. Februar 2014, 12:56
von MarcelF6
Hallo zusammen,

ich würde gerne XML-Files verschiedener Sprachen miteinander vergleichen, und diejenigen, welche einander entsprechen, in einer Liste ausgeben.
Da sich oftmals sogar die Autorennamen je nach Sprache unterscheiden können, scheint mir die Websiteangabe (also die Verlinkung) die verlässlichste Quelle zu sein, um zwei XMLs zu vergleichen.
Nun meine Frage: Wie kann ich File 1 der einen Sprache nehmen, schauen, was im Tag "<filename>" steht, und dann durch all die andere Files einer anderen Sprache gehen und dort nach dem gleichen Taginhalt zu suchen?

Danke für jede Hilfe! :)

Re: XML-Tag-Vergleich

Verfasst: Dienstag 25. Februar 2014, 13:09
von snafu
Stammen die XML-Dateien alle aus der selben Quelle oder sind sie ein wild zusammengewürfelter Haufen von unterschiedlichen Portalen (oder wie auch immer man das nennen möchte)? Mit anderen Worten: Sind zum Beispiel die Bezeichnungen für die Tags und die Reihenfolge ihres Auftretens immer gleich und nur der Text, den sie umschließen, ist in unterschiedlichen Sprachen verfasst?

Re: XML-Tag-Vergleich

Verfasst: Dienstag 25. Februar 2014, 13:10
von BlackJack
@MarcelF6: Was ist denn jetzt konkret das Problem? Schreib 'ne Funktion die Dir das <filename>-Tag sucht und den Text extrahiert, mach das mit der XML-Datei für eine Sprache und dann iteriere in einer Schleife über die XML-Dateien für die anderen Sprachen, wende die Funktion an und vergleiche jeweils das Ergebnis.

Die Beschreibung „XML-Datei für eine Sprache” und „Autorennamen” sind ein wenig wenig ohne weitere Erklärungen, denn das ist beides nichts was ganz allgemein für XML-Dateien gilt, sondern anscheinend spezifisch für Deine XML-Anwendung.

Re: XML-Tag-Vergleich

Verfasst: Dienstag 25. Februar 2014, 13:11
von Hyperion
Die Frage ist jetzt wirklich Dein Ernst? Du hast doch schon in so vielen Threads etwas zu XML gefragt... da solltest Du doch mittlerweile in der Lage sein, eine Datei zu öffnen, den XML-Baum zu parsen, zu bestimmten Knoten navigieren und auch durch die Struktur zu iterieren‽

Im Grunde kann man zu Deiner sehr allgemein gestellten Frage wenig mehr sagen. Finde den Knoten ``<filename>`` im ersten Baum, iteriere über den zweiten und suche ein passendes Tag, vergleiche beide Tag-Inhalte.

Wo genau liegt denn das Problem?

(Im übrigen wird der Kontext nicht wirklich klar. Was ist die "Sprache" einer XML-Datei?)

Re: XML-Tag-Vergleich

Verfasst: Dienstag 25. Februar 2014, 13:12
von snafu
MarcelF6 hat geschrieben:Wie kann ich File 1 der einen Sprache nehmen, schauen, was im Tag "<filename>" steht, und dann durch all die andere Files einer anderen Sprache gehen und dort nach dem gleichen Taginhalt zu suchen?
Nimm einen Parser, der XPath versteht und suche dir dann den entsprechenden Text raus. In XPath wirst du dich ggf etwas einlesen müssen. Allzu kompliziert ist diese Sprache aber eigentlich nicht.

Re: XML-Tag-Vergleich

Verfasst: Dienstag 25. Februar 2014, 15:00
von MarcelF6
Ich habs mit etree gemacht.
Folgendes habe ich schon, ich frage mich nur, wie man den Durchlauf durch die Verzeichnisse (und den gesamten Code) etwas eleganter gestalten könnte.
Ich würde einfach zwei for-Schleifen verschachteln: Die erste fürs DE, die zweite fürs FR. Oder gibt es da eine andere Möglichkeit?
Danke für die Hilfe!

Code: Alles auswählen

mainXml = ET.parse("/home/XML/2012/01/d/d_2012_01_01.xml") 
root = mainXml.getroot()
img = root.find("images/image")
for child in img:
    if child.tag == "file_name":
        txtDE = child.text

FRXml = ET.parse("/home/XML/2012/01/f/f_2012_01_01.xml")
rootFR = FRXml.getroot()
imgFR = rootFR.find("images/image")
for child in imgFR:
    if child.tag == "file_name":
        txtFR = child.text

Re: XML-Tag-Vergleich

Verfasst: Dienstag 25. Februar 2014, 15:11
von Hyperion
Guck Dir doch mal Deinen Code rein optisch an! Das ist zwei mal fast vollständig identisch, von den Namen einmal abgesehen. So etwas kann man doch *sehr* einfach in eine Funktion kapseln:

Code: Alles auswählen

def get_file_name(filename):
    mainXml = ET.parse(filename)
    root = mainXml.getroot()
    img = root.find("images/image")
    for child in img:
        if child.tag == "file_name":
            return child.text

default_name = get_file_name("/home/XML/2012/01/d/d_2012_01_01.xml")
fr_name = get_file_name("/home/XML/2012/01/f/f_2012_01_01.xml")
Wenn Du nun eine Liste von XML-Dateien hast, so kannst Du die Funktion auch in einer Schleife über der Liste aufrufen oder Dir gar per list comprehension eine Ergebnisstruktur zusammenbauen.

Und was Du für ein Problem hast, haben wir bisher immer noch bloß *implizit* herausgefunden :-P

(Das Parsen war ja offenbar gar kein Problem... :roll: )

Re: XML-Tag-Vergleich

Verfasst: Dienstag 25. Februar 2014, 15:13
von Sirius3
Was hindert dich daran, den Tag direkt herauszusuchen?

Code: Alles auswählen

def get_file_name(filename):
    main = ET.parse(filename)
    return main.findtext("images/image/file_name")

Re: XML-Tag-Vergleich

Verfasst: Dienstag 25. Februar 2014, 22:38
von MarcelF6
Vielen Dank für eure Tipps und Hinweise!
Ich habe die Pfadnamen nun alle in einer Liste.
Beim Durchgehen habe ich aber noch ein Durcheinander. Ich möchte das erste File in "xml_d" nehmen und schauen, zu welem File es in "xml_f" passt. Falls sich die Texte entsprechen, sollen die beiden Pfadnamen ausgegeben werden. Wie mache ich das am besten?

(Momentan habe ich folgendes:

Code: Alles auswählen

for el in files:
    s = el.replace("[", "").replace("]", "").replace("'", "").replace('"', '').replace(",", "")
    try:
        if s[40:48] == "01/xml_d":
            de = get_file_name(s)
	    for ele in files:
		t = ele.replace("[", "").replace("]", "").replace("'", "").replace('"', '').replace(",", "")
		if t[40:48] == "01/xml_f":
		    fr = get_file_name(t)
		    if de == fr:
		        print s + "\t" + t
    except:
	pass
)

Re: XML-Tag-Vergleich

Verfasst: Dienstag 25. Februar 2014, 23:09
von BlackJack
@MarcelF6: Was sind denn das für furchtbare Namen, die sind ja absolut nichtssagend. Und wie kommen die Elemente von `files` zustande? Wie sieht denn so ein Element aus?

Warum ignorierst Du da so grosszügig *alle* Ausnahmen?

Re: XML-Tag-Vergleich

Verfasst: Mittwoch 26. Februar 2014, 08:31
von Hyperion
Ich würde sagen, vergiss erst mal den Code und zeige uns auch keinen mehr. Zeige uns mal ein Beispiel von XML-Dateien und beschreibe, was Du mit diesen tun willst. Ansonsten kapieren wir hier immer weniger glaube ich...

Re: XML-Tag-Vergleich

Verfasst: Sonntag 2. März 2014, 22:46
von MarcelF6
Hat alles geklappt, vielen Dank für die Inputs!

Eine Frage habe ich aber noch. Wenn ich ein xml der folgenden Form habe:

Code: Alles auswählen

<?xml version="1.0"?>
<data>
    <country name="Liechtenstein">
        <rank updated="yes">2</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <rank updated="yes">5</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
</data>
Wie kann ich das File so einlesen, dass ich den gesamten Inhalt von 'data' habe?
Also konkret: Wieso erhalte ich bei folgendem Code ein leerer String und nicht den gesamten Inhalt?

Code: Alles auswählen

mainXml = ET.parse(xml_file)
	root = mainXml.getroot()
	print root.text

Re: XML-Tag-Vergleich

Verfasst: Sonntag 2. März 2014, 23:14
von BlackJack
@MarcelF6: Weil das <data>-Element keinen Text enthält. Es enthält weitere Elemente.

Re: XML-Tag-Vergleich

Verfasst: Montag 3. März 2014, 01:57
von MarcelF6
Ok, dann muss ich also alle Elemente hinzufügen?
Ist es nicht möglich, den gesamten Inhalt in data zu "lesen"?
Ich möchte sowas machen, bekomme aber eine Fehlermeldung.

Code: Alles auswählen

mainXml = ET.parse(xml_file)
	root = mainXml.find("data")
	root.append(self._findAlignment(os.path.basename(listOfPaths[0]))) # 'NoneType' object has no attribute 'append' 
        

Re: XML-Tag-Vergleich

Verfasst: Montag 3. März 2014, 06:14
von Sirius3
@MarcelF6: Dir ist schon klar, was die Fehlermeldung bedeutet? »find« sucht unterhalb des Root-Knotens nach "data" was es natürlich nicht gibt, weil "data" der Root-Knoten ist. Den gesamten Text kann man mit »itertext« durchgehen, ich kann mir aber bei Deinen Daten keine sinnvolle Verwendung dafür ausdenken. Was willst Du wirklich tun?