2012-02-16 102 views
4

我正在使用一些google的數據API,在python中使用lxml庫。命名空間在這裏是一個巨大的麻煩。對於我正在做的很多工作(主要是xpath的東西),只是簡單地忽略它們會很好。刪除lxml中的所有命名空間?

是否有一種簡單的方法可以忽略python/lxml中的xml名稱空間?

謝謝!

+3

相關:[通過一個XSL轉換除去命名空間(http://stackoverflow.com/a/4256126/4279) – jfs 2012-02-16 20:01:40

回答

1

如果你想從元素和屬性中刪除所有的命名空間,我建議下面顯示的代碼。

上下文:在我的應用程序中,我正在獲取SOAP響應流的XML表示,但我對構建客戶端上的對象不感興趣;我只對XML表示本身感興趣。而且,我對任何命名空間的東西都不感興趣,這隻會使我的目的變得比他們需要的更復雜。所以,我只是從元素中刪除名稱空間,並刪除包含名稱空間的所有屬性。

def dropns(root): 
    for elem in root.iter(): 
     parts = elem.tag.split(':') 
     if len(parts) > 1: 
      elem.tag = parts[-1] 
     entries = [] 
     for attrib in elem.attrib: 
      if attrib.find(':') > -1: 
       entries.append(attrib) 
     for entry in entries: 
      del elem.attrib[entry] 

# Test case 
name = '~/tmp/mantisbt/test.xml' 
f = open(name, 'rb') 
import lxml.etree as etree 
parser = etree.XMLParser(ns_clean=True, recover=True) 
root = etree.parse(f, parser=parser) 
print('=====================================================================') 
print etree.tostring(root, pretty_print = True) 
print('=====================================================================') 
dropns(root) 
print etree.tostring(root, pretty_print = True) 
print('=====================================================================') 

它打印:

===================================================================== 
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> 
    <SOAP-ENV:Body> 
    <ns1:mc_issue_getResponse> 
     <return xsi:type="tns:IssueData"> 
     <id xsi:type="xsd:integer">356</id> 
     <view_state xsi:type="tns:ObjectRef"> 
      <id xsi:type="xsd:integer">10</id> 
      <name xsi:type="xsd:string">public</name> 
     </view_state> 
    </return> 
    </ns1:mc_issue_getResponse> 
</SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 
===================================================================== 
<Envelope> 
    <Body> 
    <mc_issue_getResponse> 
     <return> 
     <id>356</id> 
     <view_state> 
      <id>10</id> 
      <name>public</name> 
     </view_state> 
    </return> 
    </mc_issue_getResponse> 
</Body> 
</Envelope> 
===================================================================== 
-1

In lxml some_element.tag是一個像{namespace-uri}local-name這樣的字符串,如果有名稱空間的話,只需local-name否則。請注意,它是非元素節點上的非字符串值(如註釋)。

試試這個:

for node in some_tree.iter(): 
    startswith = getattr(node 'startswith', None) 
    if startswith and startswith('{'): 
     node.tag = node.tag.rsplit('}', 1)[-1] 

關於Python 2.x的標籤可以是一個ASCII字節字符串或Unicode字符串。一個startswith方法的存在測試。