2015-01-07 108 views
1

我有一個XML使用ElementTree的命名空間,它的小部分看起來是這樣的:解析XML使用Python

<?xml version="1.0" ?> 
<i:insert xmlns:i="urn:com:xml:insert" xmlns="urn:com:xml:data"> 
    <data> 
    <image imageId="1"></image> 
    <content>Content</content> 
    </data> 
</i:insert> 

當我把它用ElementTree並將其保存到一個文件,我看到以下解析:

<ns0:insert xmlns:ns0="urn:com:xml:insert" xmlns:ns1="urn:com:xml:data"> 
    <ns1:data> 
    <ns1:image imageId="1"></ns1:image> 
    <ns1:content>Content</ns1:content> 
    </ns1:data> 
</ns0:insert> 

爲什麼它會改變前綴並將它們放在任何地方?使用minidom我沒有這樣的問題。它是否配置? ElementTree的文檔非常差。 問題是,我無法找到任何節點後,這樣的解析,例如image - 無法找到它有或沒有命名空間,如果我使用它像{namespace}image或只是image。爲什麼?任何建議,強烈感激。

什麼我已經嘗試過:

import xml.etree.ElementTree as ET 
tree = ET.parse('test.xml') 
root = tree.getroot() 
for a in root.findall('ns1:image'): 
    print a.attrib 

這會返回一個錯誤,而另一個沒有返回:

for a in root.findall('{urn:com:xml:data}image'): 
    print a.attrib 

我也試圖使命名空間像這樣使用它:

namespaces = {'ns1': 'urn:com:xml:data'} 
for a in root.findall('ns1:image', namespaces): 
    print a.attrib 

它什麼都沒有返回。我究竟做錯了什麼?

+0

您可以添加用於解析XML的Python代碼嗎? –

回答

1

該片段從你的問題,

for a in root.findall('{urn:com:xml:data}image'): 
    print a.attrib 

不輸出任何東西,因爲它只會尋找樹的根的直接{urn:com:xml:data}image孩子。

這略微修改後的代碼,

for a in root.findall('.//{urn:com:xml:data}image'): 
    print a.attrib 

將打印{'imageId': '1'},因爲它使用.//,它選擇在所有層面匹配的子元素。

參考:https://docs.python.org/2/library/xml.etree.elementtree.html#supported-xpath-syntax


這是一個有點討厭的是ElementTree的不只是默認情況下,保留了原有的命名空間前綴,但請記住,這不是前綴此事反正。當序列化爲 XML時,register_namespace()函數可用於設置所需的前綴。該功能對解析或搜索沒有任何影響。

0

從我收集的內容來看,它與ET中的命名空間識別有關。

從這裏http://effbot.org/zone/element-namespaces.htm

當您保存元素樹XML,標準的元素串生成所有URI唯一的前綴:出現在樹秒。前綴通常具有「ns」後跟數字的形式。例如,上述元素可能會以「http://www.w3.org/1999/xhtml」的前綴ns0和「http://effbot.org/namespace/letters」的ns1作爲序列號。

如果您想要使用特定的前綴,可以在ElementTree模塊的全局表中添加前綴/ URI映射。在1.3及更高版本中,您可以通過調用register_namespace函數來完成此操作。在早期版本中,可以訪問直接內部表:

ElementTree的1.3

ET.register_namespace(前綴,URI)

ElementTree的1.2(Python 2.5中)

ET._namespace_map [URI] =前綴

請注意參數順序;該函數首先獲取前綴,而原始字典則從URI:s映射到前綴。

+0

我已經讀過它並嘗試過這個命名空間註冊,但它沒有幫助。 – tinySandy