2014-01-05 43 views
3

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

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

<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:前缀和没有前缀的Cell和Data元素。然而,声明说,这两个属于同一个模式'urn:schemas-microsoft-com:office:spreadsheet',那么解析器应该等价地对待它们吗?

<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')); 

回答

2

根据The lxml.etree Tutorial -- Namespace

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


BTW,以下

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

可以写为:

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

或:

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

谢谢,我想关键的一点是,我使用了ElementTree的API访问属性,但XPath访问元素? – user2981639

+1

@ user2981639,我不明白你在评论中的问题。你想在row.xpath('./ ss:Cell/ss:Data/@ ss:Type',namespaces = namespaces)中使用'for data_type:print data_type'吗? – falsetru

+0

这不仅仅是一个陈述而是一个问题,我希望能够一致地访问元素和属性,即使用ss:或者全名称空间作为前缀。在我的示例代码中,我必须在ssl中为元素添加前缀:在我的xpath查询中,但是当我访问该元素的属性时,我必须使用{urn:schemas-microsoft-com:office:spreadsheet}语法。这不是一个真正的问题,但似乎有点不寻常,因为我以前从来没有用过这种语法的XML解析器。 – user2981639