如何在阅读大型XML时系统地避免或忽略子索引超出范围

时间:2016-04-20 23:52:31

标签: python xml python-3.x xml-parsing

我正在阅读超过106.000条目的大型XML。每个条目都是一组具有大量信息的研究人员。我做了一个阅读功能。

但是,如果在任何时候缺少任何信息,我会得到

  

IndexError:子索引超出范围

当孩子失踪时,有没有办法告诉程序忽略

由于数据的多样性,我可能会为每个收集的数据提供不同大小的信息。

每次检查可能不是一个好主意,例如:

if root[0]0][0][0]:
    tot_nac_2011 = int(root[0][0][0][0].attrib['TOT-BIBL-PERIODICO-NAC']

这是我的代码

from xml.etree import ElementTree
extended = ElementTree.parse('0000301510136952_2014_estendido.xml')

def read_researcher(extended):
    root = extended.getroot()
    members = []
    for each in range(len(root[0])):
        group_id = root.attrib['NRO-ID-GRUPO']
        research_id = root[0][each].attrib['NRO-ID-CNPQ']
        name = root[0][each].attrib['NOME-COMPLETO']
        tit = root[0][each].attrib['TITULACAO-MAXIMA']
        sex = root[0][each].attrib['SEXO']
        tot_nac_2011 = int(root[0][each][0][0].attrib['TOT-BIBL-PERIODICO-NAC'])
        tot_nac_2014 = int(root[0][each][0][3].attrib['TOT-BIBL-PERIODICO-NAC'])
        tot_int_2011 = int(root[0][each][0][0].attrib['TOT-BIBL-PERIODICO-INT'])
        tot_int_2014 = int(root[0][each][0][3].attrib['TOT-BIBL-PERIODICO-INT'])
        tot_bbl_2011 = int(root[0][each][0][0].attrib['TOT-BIBL'])
        tot_bbl_2014 = int(root[0][each][0][3].attrib['TOT-BIBL'])
        members.append(researchers.Researcher(group_id, research_id, name, tit, sex, tot_nac_2011, tot_nac_2014, tot_int_2011, tot_int_2014, tot_bbl_2011, tot_bbl_2014))
    return members

1 个答案:

答案 0 :(得分:1)

回答您的具体问题:通过try / except使用异常处理,并处理从子元素中提取属性值时可能发生的相关错误。这是EAFP编程风格。还有LBYL个。

我还会使用中间字典改进代码来处理Researcher对象初始化参数,从循环下移动group_id,因为我们是从根元素获取它。

代码:

from xml.etree import ElementTree


extended = ElementTree.parse('0000301510136952_2014_estendido.xml')


def get_value(item, index, value):
    try:
        return int(item[index].attrib[value])
    except (IndexError, KeyError, AttributeError, ValueError):
        # TODO: log
        return None


def read_researcher(extended):
    root = extended.getroot()
    group_id = root.attrib['NRO-ID-GRUPO']

    members = []
    for item in root[0]:
        subitem = item[0]
        researcher = {
            "group_id": group_id,
            "research_id": item.attrib.get('NRO-ID-CNPQ'),
            "name": item.attrib.get('COMPLETO'),
            "tit": item.attrib.get('TITULACAO-MAXIMA'),
            "sex": item.attrib.get('SEXO'),
            "tot_nac_2011": get_value(subitem, 0, 'TOT-BIBL-PERIODICO-NAC'),
            "tot_nac_2014": get_value(subitem, 3, 'TOT-BIBL-PERIODICO-NAC'),
            "tot_int_2011": get_value(subitem, 0, 'TOT-BIBL-PERIODICO-INT'),
            "tot_int_2014": get_value(subitem, 3, 'TOT-BIBL-PERIODICO-INT'),
            "tot_bbl_2011": get_value(subitem, 0, 'TOT-BIBL'),
            "tot_bbl_2014": get_value(subitem, 3, 'TOT-BIBL'),
        }

        members.append(researchers.Researcher(**researcher))
    return members