删除lxml中的所有名称空间?

时间:2012-02-16 17:33:08

标签: python xml api lxml

我正在使用谷歌的一些数据API,使用python中的lxml库。命名空间在这里是一个巨大的麻烦。对于我正在做的很多工作(主要是xpath的东西),简单地忽略它们会很好。

有没有一种简单的方法可以忽略python / lxml中的xml命名空间?

谢谢!

2 个答案:

答案 0 :(得分: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 :(得分:-1)

在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方法测试。