Python-ElementTree-Modul: How to ignorieren Sie den namespace des XML-Dateien zu suchen von übereinstimmenden element bei Verwendung der Methode "find", "findall"
Möchte ich die Methode "findall" zu suchen, einige Elemente der Quell-xml-Datei in der ElementTree-Modul.
Jedoch das Quell-xml-Datei (test.xml) hat namespace. Ich truncate-Teil der xml-Datei als Beispiel:
<?xml version="1.0" encoding="iso-8859-1"?>
<XML_HEADER xmlns="http://www.test.com">
<TYPE>Updates</TYPE>
<DATE>9/26/2012 10:30:34 AM</DATE>
<COPYRIGHT_NOTICE>All Rights Reserved.</COPYRIGHT_NOTICE>
<LICENSE>newlicense.htm</LICENSE>
<DEAL_LEVEL>
<PAID_OFF>N</PAID_OFF>
</DEAL_LEVEL>
</XML_HEADER>
Das Beispiel python code ist unten:
from xml.etree import ElementTree as ET
tree = ET.parse(r"test.xml")
el1 = tree.findall("DEAL_LEVEL/PAID_OFF") # Return None
el2 = tree.findall("{http://www.test.com}DEAL_LEVEL/{http://www.test.com}PAID_OFF") # Return <Element '{http://www.test.com}DEAL_LEVEL/PAID_OFF' at 0xb78b90>
Obwohl es funktioniert, weil es einen Namensraum "{http://www.test.com}", es ist sehr unbequem für einen namespace hinzuzufügen vor jedem tag.
Wie kann ich ignorieren Sie den Namensraum bei der Verwendung der Methode "find", "findall" und so weiter?
- Ist
tree.findall("xmlns:DEAL_LEVEL/xmlns:PAID_OFF", namespaces={'xmlns': 'http://www.test.com'})
bequem genug? - Dank sehr viel. Ich versuche Ihre Methode und es funktioniert. Es ist bequemer als meins aber es ist immer noch ein wenig umständlich. Wissen Sie, ob es gibt keine andere richtige Methode in der ElementTree-Modul um dieses Problem zu lösen, oder es gibt keine solche Methode überhaupt?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Statt einer änderung des XML-Dokuments selbst, ist es am besten, zu analysieren und dann ändern Sie die tags in das Ergebnis. Auf diese Weise können Sie den Umgang mit mehreren namespaces und namespace-Aliase:
Dies ist auf der Grundlage der Diskussion hier:
http://bugs.python.org/issue18304
et.findall('{*}sometag')
. Und es ist auch mangeln die element-Baum selbst, nicht nur "die Suche ausführen, ignorieren von namespaces nur dieses eine mal, ohne re-Parsen das Dokument, etc, unter Beibehaltung der namespace-Informationen". Naja, für den Fall, dass Sie observably müssen Durchlaufen den Baum, und sehen Sie selbst, wenn die nodes Ihre Wünsche nach dem entfernen des Namespaces.Wenn Sie entfernen das xmlns-Attribut aus der xml-vor der Analyse ist es dann nicht ein namespace vorangestellt, um jeden tag in den Baum.
Den Antworten, die bisher explizit setzen den namespace-Wert in das Skript. Für eine allgemeinere Lösung, würde ich lieber extrahieren Sie den namespace aus der xml:
Und verwenden Sie es in der find-Methode:
namespace
Hier ist eine Erweiterung, nonagon Antwort, die auch Streifen-namespaces off attributes:
Verbesserung auf die Antwort von ericspod:
Anstelle der änderung des parse-Modus weltweit können wir wickeln diese in ein Objekt, die Unterstützung der mit-Konstrukt.
Diese können dann wie folgt verwendet werden
Die Schönheit dieses Weges ist, dass es sich nicht ändern kein Verhalten für die Ausgabe von code außerhalb der with-block. Ich landete diese nach Fehler erhalten Sie in andere Bibliotheken nach der Verwendung der version von ericspod was auch geschah zu verwenden expat.
Können Sie die elegante string formatieren konstruieren sowie:
oder, wenn du sicher bist, dass PAID_OFF erscheint nur in einer Ebene im Baum:
Wenn Sie
ElementTree
und nichtcElementTree
können Sie erzwingen, dass der Expat zu ignorieren namespace Verarbeitung durch den AustauschParserCreate()
:ElementTree
versucht, Expat durch den AufrufParserCreate()
bietet aber keine option, um keine namespace-separator-string, der obige code bewirkt, dass es zu ignorieren, aber seien Sie gewarnt, dies könnte brechen andere Dinge.ElementTree.fromstring(s, parser=None)
ich versuche zu pass-parser zu.Könnte ich zu spät sein für das, aber ich glaube nicht, dass
re.sub
ist eine gute Lösung.Jedoch das umschreiben
xml.parsers.expat
funktioniert nicht für Python 3.x-Versionen,Der Hauptschuldige ist der
xml/etree/ElementTree.py
siehe unten im QuellcodeIst irgendwie traurig.
Die Lösung ist, um loszuwerden, der es zuerst.
Getestet auf Python 3.6.
Versuchen
try
- Anweisung ist nützlich, falls Sie irgendwo in Ihrem code, den Sie laden oder importieren Sie ein Modul zweimal bekommen Sie einige seltsame Fehler, wiebtw verdammt etree Quellcode sieht wirklich chaotisch.