Python ElementTree modul: Bagaimana untuk mengabaikan namespace XML file untuk menemukan pencocokan elemen ketika menggunakan metode "cari", "findall"
Saya ingin menggunakan metode "findall" untuk menemukan beberapa elemen dari sumber file xml di ElementTree modul.
Namun, sumber file xml (test.xml) memiliki namespace. Aku memotong bagian dari file xml sebagai contoh:
<?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>
Sampel kode python di bawah ini:
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>
Meskipun hal ini dapat bekerja, karena ada namespace "{http://www.test.com", it's sangat nyaman untuk menambahkan namespace di depan masing-masing tag.
Bagaimana bisa aku mengabaikan namespace ketika menggunakan metode "cari", "findall" dan sebagainya?
118
9
Bukan memodifikasi dokumen XML itu sendiri,'s terbaik untuk mengurai dan kemudian memodifikasi kategori dalam hasil. Dengan cara ini anda dapat menangani beberapa namespaces dan nama alias:
Hal ini didasarkan pada pembahasan berikut ini: http://bugs.python.org/issue18304
Jika anda menghapus atribut xmlns dari xml sebelum parsing itu maka tidak ada't menjadi namespace ditambahkan untuk setiap tag di pohon.
Jawaban yang sejauh ini secara eksplisit menempatkan namespace nilai dalam script. Untuk lebih generik solusi, saya lebih suka ekstrak namespace dari xml:
Dan menggunakannya dalam menemukan metode:
Berikut ini's ekstensi untuk nonagon's jawaban, yang juga strip namespaces off atribut:
Peningkatan pada jawaban oleh ericspod:
Bukan mengubah mengurai mode secara global bisa kita bungkus ini di sebuah objek yang mendukung dengan membangun.
Ini kemudian dapat digunakan sebagai berikut
Keindahan dari cara ini adalah bahwa hal itu tidak mengubah perilaku yang tidak terkait kode luar dengan blok. Akhirnya saya membuat ini setelah mendapatkan kesalahan dalam berhubungan perpustakaan setelah menggunakan versi ericspod yang juga terjadi untuk menggunakan expat.
Anda dapat menggunakan elegan string pemformatan membangun serta:
atau, jika anda're yakin bahwa PAID_OFF hanya muncul di satu tingkat di pohon:
Jika anda're menggunakan
ElementTree
dan tidakcElementTree
anda dapat memaksa Expat untuk mengabaikan namespace pengolahan dengan menggantiParserCreate()
:ElementTree
mencoba untuk menggunakan Expat dengan memanggilParserCreate()
tetapi tidak memberikan pilihan untuk tidak memberikan namespace pemisah string, kode di atas akan menyebabkan itu untuk mengabaikan tapi berhati-hatilah, ini bisa memecahkan hal-hal lain.Let's menggabungkan nonagon's jawaban dengan mzjn's jawaban untuk pertanyaan terkait:
Dengan menggunakan fungsi ini kita:
Membuat sebuah iterator untuk mendapatkan kedua namespaces dan parsing tree objek.
Iterate atas dibuat iterator untuk mendapatkan namespaces dict yang kita dapat kemudian lulus dalam masing-masing
find()
ataufindall()
call sebagai sugested oleh iMom0.Kembali diurai pohon's elemen root objek dan namespaces.
Saya pikir ini adalah pendekatan yang terbaik di sekitar karena ada's tidak ada manipulasi baik dari sumber XML atau dihasilkan diurai
xml.etree.ElementTree
output apapun yang terlibat.I'd seperti juga untuk kredit barny's jawaban dengan menyediakan bagian penting dari teka-teki ini (bahwa anda bisa mendapatkan diurai akar dari iterator). Sampai aku benar-benar dilalui pohon XML dua kali di aplikasi saya (sekali untuk mendapatkan namespaces, kedua untuk root).
Saya mungkin terlambat untuk ini, tapi saya tidak berpikir
kembali.sub
adalah solusi yang baik.Namun menulis ulang
xml.parsers.expat
tidak bekerja untuk Python 3.x versi,Penyebab utama adalah
xml/etree/ElementTree.py
lihat bagian bawah dari kode sumberYang agak sedih.
Solusinya adalah dengan menyingkirkan terlebih dahulu.
Diuji pada Python 3.6.
Coba
coba-coba
pernyataan ini berguna dalam kasus di suatu tempat dalam kode anda anda reload atau mengimpor modul dua kali anda mendapatkan beberapa kesalahan aneh sepertibtw sialan dpohon source code terlihat benar-benar berantakan.