2012-09-20 123 views
1

我在使用lxml 2.3和etree命名空間時遇到問題。使用lxml etree衝突命名空間

例如,我有不同的命名空間的兩個節點:

parent = etree.Element('{parent-space}parent') 
child = etree.Element('{child-space}child') 

之後,child節點附加到parent節點:

parent.append(child) 

然後,如果我使用etree的tostring方法,我得到以下輸出:

<ns0:parent xmlns:ns0="parent-space"> 
    <ns0:child xmlns:ns0="child-space"/> 
</ns0:parent> 

這兩個命名空間都在此處獲得標籤ns0,因此它們發生衝突。我怎樣才能避免這種情況?

回答

3

沒有衝突。前ns0前綴僅爲<child>的後代覆蓋。

這份XML文檔

<ns0:parent xmlns:ns0="parent-space"> 
    <ns0:child xmlns:ns0="child-space"/> 
</ns0:parent> 

相當於

<ns0:parent xmlns:ns0="parent-space"> 
    <ns1:child xmlns:ns1="child-space"/> 
</ns0:parent> 

<parent xmlns="parent-space"> 
    <child xmlns="child-space"/> 
</parent> 

儘可能的parentchild去有效的命名空間。

你可以使用nsmap來聲明前綴。有效的結果是相同的,但在序列化時看起來不那麼令人困惑。

from lxml import etree 

NS_MAP = { 
    "p" : "http://parent-space.com/", 
    "c" : "http://child-space.com/" 
} 
NS_PARENT = "{%s}" % NS_MAP["parent"] 
NS_CHILD = "{%s}" % NS_MAP["child"] 

parent = etree.Element(NS_PARENT + "parent", nsmap=NS_MAP) 
child = etree.SubElement(parent, NS_CHILD + "child") 
child.text = "Some Text" 

print etree.tostring(parent, pretty_print=True) 

此打印

<p:parent xmlns:p="http://parent-space.com/" xmlns:c="http://child-space.com/"> 
    <c:child>Some Text</c:child> 
</p:parent>