Чтение электронной таблицы, такой как .xml, с ElementTree - PullRequest
0 голосов
/ 09 января 2019

Я читаю XML-файл, используя ElementTree, но есть ячейка, в которой я не могу прочитать его данные.

Я адаптировал свой файл, чтобы сделать воспроизводимый пример, который я представляю следующим образом:

from xml.etree import ElementTree
import io

xmlf = """<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook ss:ResourcesPackageName="" ss:ResourcesPackageVersion="" xmlns="urn:schemas-microsoft-com:office:spreadsheet"
 xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
 xmlns:html="http://www.w3.org/TR/REC-html40">
  <Worksheet ss:Name="DigitalOutput" ss:IsDeviceType="true">
     <Row ss:AutoFitHeight="0">
    <Cell><Data ss:Type="String">A</Data><NamedCell ss:Name="_FilterDatabase"/></Cell>
    <Cell><Data ss:Type="String">B</Data><NamedCell ss:Name="_FilterDatabase"/></Cell>
    <Cell><Data ss:Type="String">C</Data><NamedCell ss:Name="_FilterDatabase"/></Cell>
    <Cell ss:Index="7"><ss:Data ss:Type="String"
      xmlns="http://www.w3.org/TR/REC-html40"><Font html:Color="#000000">CAN'T READ </Font><Font>THIS</Font></ss:Data><NamedCell
      ss:Name="_FilterDatabase"/></Cell>
    <Cell ss:Index="10"><Data ss:Type="String">D</Data><NamedCell
      ss:Name="_FilterDatabase"/></Cell>
   </Row>
   </Worksheet>
 </Workbook>"""

ss = "urn:schemas-microsoft-com:office:spreadsheet"
worksheet_label = '{%s}Worksheet' % ss
row_label = '{%s}Row' % ss
cell_label = '{%s}Cell' % ss
data_label = '{%s}Data' % ss

tree = ElementTree.parse(io.StringIO(xmlf))
root = tree.getroot()

for ws in root.findall(worksheet_label):
    for table in ws.findall(row_label):
        for c in table.findall(cell_label):
            data = c.find(data_label)
            print(data.text)

Вывод:

A
B
C
None
D

Итак, четвертая ячейка не была прочитана. Можете ли вы помочь мне исправить это?

Ответы [ 2 ]

0 голосов
/ 09 января 2019

Вопрос : чтение электронных таблиц, таких как .xml, с ElementTree

Документация: Учебное пособие по lxml.etree - Пространства имен


  1. Определите namespaces используемый

    ns = {'ss':"urn:schemas-microsoft-com:office:spreadsheet",
          'html':"http://www.w3.org/TR/REC-html40"
         }
    
  2. Используйте namespaces с find(.../findall(...

    tree = ElementTree.parse(io.StringIO(xmlf))
    root = tree.getroot()
    
    for ws in root.findall('ss:Worksheet', ns):
        for table in ws.findall('ss:Row', ns):
            for c in table.findall('ss:Cell', ns):
                data = c.find('ss:Data', ns)
                if data.text is None:
                    text = []
                    data = data.findall('html:Font', ns)
                    for element in data:
                        text.append(element.text)
    
                    data_text = ''.join(text)
                    print(data_text)
                else:
                    print(data.text)
    

выход

A
B
C
CAN'T READ THIS
D

Протестировано на Python: 3,5

0 голосов
/ 09 января 2019

Текстовое содержимое четвертой ячейки принадлежит двум Font подэлементам, которые связаны с другим пространством имен. Демонстрация:

for e in root.iter():
    text = e.text.strip() if e.text else None 
    if text:
        print(e, text)

Выход:

<Element {urn:schemas-microsoft-com:office:spreadsheet}Data at 0x7f8013d01dc8> A
<Element {urn:schemas-microsoft-com:office:spreadsheet}Data at 0x7f8013d01dc8> B
<Element {urn:schemas-microsoft-com:office:spreadsheet}Data at 0x7f8013d01dc8> C
<Element {http://www.w3.org/TR/REC-html40}Font at 0x7f8013d01e08> CAN'T READ
<Element {http://www.w3.org/TR/REC-html40}Font at 0x7f8013d01e48> THIS
<Element {urn:schemas-microsoft-com:office:spreadsheet}Data at 0x7f8013d01e48> D
...