将数据从XML提取到字典中(1行作为键,下一行作为项)

时间:2017-09-30 02:42:48

标签: python xml dictionary

我有一个XML文件,其中包含摘要信息标题和后面的主数据表。我已将主数据表输出到pd.df,但现在我想将部分标题信息提取到字典中。

XML档案的示例:

<Workbook>
 <Worksheet>
  <Tables>
   <Row>
    <Cell ss:StyleID="HeadTableTitle" ss:MergeAcross="1"><Data ss:Type="String">Administrative Data</Data></Cell>
   </Row>
   <Row>
    <Cell ss:StyleID="HeadTableParameterName" ss:MergeAcross="1"><Data ss:Type="String">ID</Data></Cell>
    <Cell ss:StyleID="HeadTableParameterValue" ss:MergeAcross="7"><Data ss:Type="String">B013</Data></Cell>
   </Row>
   <Row>
    <Cell ss:StyleID="HeadTableParameterName" ss:MergeAcross="1"><Data ss:Type="String">Title</Data></Cell>
    <Cell ss:StyleID="HeadTableParameterValue" ss:MergeAcross="7"><Data ss:Type="String">Mr</Data></Cell>
   </Row>
   <Row>
    <Cell ss:StyleID="HeadTableParameterName" ss:MergeAcross="1"><Data ss:Type="String">Last Name</Data></Cell>
    <Cell ss:StyleID="HeadTableParameterValue" ss:MergeAcross="7"><Data ss:Type="String">Data</Data></Cell>
   </Row>
   <Row>
    <Cell ss:StyleID="HeadTableParameterName" ss:MergeAcross="1"><Data ss:Type="String">First Name</Data></Cell>
    <Cell ss:StyleID="HeadTableParameterValue" ss:MergeAcross="7"><Data ss:Type="String">Test</Data></Cell>
   </Row>
   <Row/>
   <Row/>
   <Row>
    <Cell ss:StyleID="HeadTableTitle" ss:MergeAcross="1"><Data ss:Type="String">Biological and Medical Baseline Data</Data></Cell>
   </Row>
   <Row>
    <Cell ss:StyleID="HeadTableParameterName" ss:MergeAcross="1"><Data ss:Type="String">Height</Data></Cell>
    <Cell ss:StyleID="HeadTableParameterValue" ss:MergeAcross="7"><Data ss:Type="String">176 cm</Data></Cell>
   </Row>
   <Row>
    <Cell ss:StyleID="HeadTableParameterName" ss:MergeAcross="1"><Data ss:Type="String">Weight</Data></Cell>
    <Cell ss:StyleID="HeadTableParameterValue" ss:MergeAcross="7"><Data ss:Type="String">56.9 kg</Data></Cell>
   </Row>
  </Tables>
 </Worksheet>
</Workbook>

我希望能够在“管理数据”中提取数据。在第一个&#39;单元格&#39;值作为键(如果我可以删除那些令人敬畏的空格),以及第二个&#39;单元格&#39;值作为项目。然后需要重复这一过程,以便生物和医学基线数据中的数据能够被重复。是在一个单独的字典中。字典名称可以是任何名称(例如&#39;主题&#39;和&#39; biomed&#39;)

解析XML文件并访问代码的当前代码:

from lxml import etree

f_path = 'data store/cortex_full.xml'  # enter path of xml file

# open and parse xml file
with open(f_path, 'r', encoding='utf-8') as f:  # set encoding to utf-8 for mac
    root = 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 = root.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)

有关如何处理此问题的任何建议?如果字典不是可选的,也很乐意使用其他建议。

1 个答案:

答案 0 :(得分:1)

确保在

之前声明以下内容
subject={}
bio={}
d=None  #If this doesn't work then use d={}

考虑更换

for row in rows:
   cells = row.xpath('./ss:Cell/ss:Data', namespaces=namespaces)

        for row in rows:
            cells = row.xpath('./ss:Cell', namespaces=namespaces)
            if(len(cells)==2):
              key=None
              item=None
              for cell in cells:
                if(cell.attrib['{urn:schemas-microsoft-com:office:spreadsheet}StyleID']=="HeadTableParameterName"):
                  key=cell.xpath('./ss:Data', namespaces=namespaces)[0].text.strip()
                else:
                  item=cell.xpath('./ss:Data', namespaces=namespaces)[0].text.strip()
              if(not(key==None or item==None)):
                d[key]=item
            elif len(cells)==1:
              if(cells[0].attrib['{urn:schemas-microsoft-com:office:spreadsheet}StyleID']=='HeadTableTitle'):
                if(cells[0].xpath('./ss:Data', namespaces=namespaces)[0].text=='Biological and Medical Baseline Data'):
                  d=bio
                else:
                  d=subject
print(bio)
print(subject)

虽然没有必要,但我只是为了给出一个想法而进行了一些检查,但你可以扩展检查以使其更加健壮。

我还有一个正常工作的版本here