1. 程式人生 > 實用技巧 >Python 解析含有名稱空間(xmlns)的xml檔案(基於ElementTree)

Python 解析含有名稱空間(xmlns)的xml檔案(基於ElementTree)

Outline

為什麼會有名稱空間?

XML的元素名字是不固定的,當兩個不同的文件,使用同樣的名稱描述兩個不同型別的元素的時候,或者一個同樣的標記表示兩個不同含義的內容的時候,就會發生命名衝突。

這時,名稱空間是可以解決這個問題的;

名稱空間(Namespace),對於每一套特定應用的DTD,給它一個獨一無二的標誌來代表,如果在XML中使用DTD中定義的元素,需將 DTD的標誌和元素名,屬性連在一起使用,相當於指明瞭元素來自什麼地方,這樣就不會同其他同名元素混淆了。

名稱空間允許我們在一個文件中結合不同的元素和屬性定義,並指明這些元素和屬性的定義來自那裡。 名稱空間語法結構:
xmlns:[prefix]=”[url of name]”
其中“xmlns:”是必須的屬性。“prefix”是名稱空間的別名,它的值不能為xml。
 
<sample xmlns:ins=”http://www.lsmx.net.ac”> <ins:batch-list> <ins:batch>Evening Batch</ins:batch> </ins:batch-list> </sample>

遇到的問題

在用ElementTree解析xml時,一直很順利,都能解析成功;但突然出現解析不出xml情況,文字編輯器開啟xml文件發現裡面是有內容的;
仔細觀察了下發現根標籤中有一個 xmlns 屬性,查了下原來是 名稱空間, xml中有名稱空間的情況下,獲取子標籤內容的話,就需要通過名稱空間去唯一標識這個標籤。

現在知道xml檔案中的xmlns了,剩下就是結合xmlns解析資料了;

debug觀察標籤情況

簡單debug下,看下包含xmlns的標籤是什麼樣子的;

發現包含名稱空間的xml,解析時(或者去定位標籤時)標籤的構成是:名稱空間+標籤名

解析資料

通過上面操作已經知道當前xml文字的xmlns是什麼了,所以就直接給標籤拼接上xmlns,這樣獲取的內容就都是該名稱空間下的內容了。

import xml.etree.ElementTree as ET

path = 'C:\data\美股資料\GenInfo03_NA_i_20200609_1of1.xml\GenInfo_00B6F.xml'
tree 
= ET.parse(path) # for i in tree.iter(): # print(i.tag) root = tree.getroot() namespace = '{urn:reuterscompanycontent:generalinformation03}' iter_root = root.iter(namespace + 'GeneralInformation') # 直接給標籤拼接上xmlns ret = [] def get_xml_content(iter_root): """遞迴獲取xml標籤內容""" for node in iter_root: dic = node.attrib text = node.text if len(dic) == 0 and text == '\n': pass else: dic['text'] = text t = node.tag.split('}')[-1] ret.append({t: dic}) get_xml_content(node) get_xml_content(iter_root)

參考資訊

How does XPath deal with XML namespaces? 如何使用Python ElementTree獲取元素樹的所有子元素?