2012-02-16 103 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方法的存在测试。