lxml属性需要完整的命名空间

下面的代码使用lxml(python 3.3)从Excel 2003 XML工作簿中读取表格。 代码工作正常,但是为了通过get()方法访问Data元素的Type属性,我需要使用键'{urn:schemas-microsoft-com:office:spreadsheet} Type' – 为什么是这样的,我已经用ss前缀指定了这个命名空间。

所有我能想到的是这个命名空间在文档中出现两次,一次使用命名空间前缀,一次没有

<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:html="http://www.w3.org/TR/REC-html40"> 

在文件中,元素和属性声明如下 – 带有ss:前缀的Type属性和没有前缀的Cell和Data元素。 然而,声明说,这两个属于同一个模式“urn:schemas-microsoft-com:office:spreadsheet”,那么parsing器肯定应该把它们等价处理呢?

 <Cell><Data ss:Type="String">QB11128020</Data></Cell> 

我的代码:

 with (open(filename,'r')) as f: doc = etree.parse(f) namespaces={'o':'urn:schemas-microsoft-com:office:office', 'x':'urn:schemas-microsoft-com:office:excel', 'ss':'urn:schemas-microsoft-com:office:spreadsheet'} ws = doc.xpath('/ss:Workbook/ss:Worksheet', namespaces=namespaces) if len(ws) > 0: tables = ws[0].xpath('./ss:Table', namespaces=namespaces) if len(tables) > 0: rows = tables[0].xpath('./ss:Row', namespaces=namespaces) for row in rows: cells = row.xpath('./ss:Cell/ss:Data', namespaces=namespaces) for cell in cells: print(cell.text); print(cell.keys()); print(cell.get('{urn:schemas-microsoft-com:office:spreadsheet}Type')); 

根据lxml.etree教程 – 命名空间 :

ElementTree API尽可能地避免了命名空间前缀,而是部署了真实的命名空间(URI):


顺便说一句,以下

 cell.get('{urn:schemas-microsoft-com:office:spreadsheet}Type') 

可以写成:

 cell.get('{%(ss)s}Type' % namespaces) 

要么:

 cell.get('{{{0[ss]}}}Type'.format(namespaces))