我正在使用一些google的数据API,在python中使用lxml库。命名空间在这里是一个巨大的麻烦。对于我正在做的很多工作(主要是xpath的东西),只是简单地忽略它们会很好。删除lxml中的所有命名空间?
是否有一种简单的方法可以忽略python/lxml中的xml名称空间?
谢谢!
我正在使用一些google的数据API,在python中使用lxml库。命名空间在这里是一个巨大的麻烦。对于我正在做的很多工作(主要是xpath的东西),只是简单地忽略它们会很好。删除lxml中的所有命名空间?
是否有一种简单的方法可以忽略python/lxml中的xml名称空间?
谢谢!
如果你想从元素和属性中删除所有的命名空间,我建议下面显示的代码。
上下文:在我的应用程序中,我正在获取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>
=====================================================================
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方法的存在测试。
相关:[通过一个XSL转换除去命名空间(http://stackoverflow.com/a/4256126/4279) – jfs 2012-02-16 20:01:40