Разбор сложных XML-данных с использованием Python и сохранение их в CSV - PullRequest
0 голосов
/ 23 сентября 2019

Я работаю с образцами данных, которые не имеют стандартной структуры и имеют сложные данные.Например, рассмотрим пример XML-файла из ZIP-файлов с экстрактами больших объемов данных (из part1 или part2), который доступен по следующему URL:

https://data.gov.au/dataset/ds-dga-5bd7fcab-e315-42cb-8daf-50b7efc2027e/details

Я хочу сохранить файл CSV сСинтаксический анализ XML со столбцами: Корневой узел. Приращение при каждом вызове (с использованием тега ABR). ABN и тип объекта, Основной объект и Юридический объект, ACN, GST, Другой объект DGR,

Я попытался получить некоторые выводы, которые каждыйтег имеет некоторый отсутствующий тег при сравнении.Например, результаты, перечисленные ниже, 1) у тега, начинающегося с ABR, есть Main Entity или Legal лицо или оба, которые предоставляют деловую информацию.2) GST-тег может присутствовать в нескольких случаях или не отображаться. 3) Другой объект не имеет фиксированного числа дочерних элементов для динамического анализа.4) в общей сложности 723 тыс. Записей, которые мне нужны в CSV, я только что получил 30 тыс. Записей с приведенным ниже кодом, который у меня есть:


trail.py:
------------------------------------------------------------------------

import xml.etree.ElementTree
from lxml import etree as et


def Convert(tup, di):
    for a, b in tup:
        di.setdefault(a, []).append(b)
    return di


def make_dict_from_tree(element_tree):
    # print(element_tree.tag)

    def internal_iter(tree, accum):
        if len(tree.items()) > 0:
            for i in tree.items():
                accum[tree.tag + "-" + i[0]] = i[1]
            # print(tree.text,tree.tag,tree.items())
        # print(tree.tag)
        if tree.text is not None :
            accum[tree.tag] = tree.text
        if tree is None:
            # print(accum)
            return accum

        if tree.getchildren():
            accum[tree.tag] = {}
            for each in tree.getchildren():
                result = internal_iter(each, {})
                if each.tag in accum[tree.tag]:
                    if not isinstance(accum[tree.tag][each.tag], list):
                        accum[tree.tag][each.tag] = [
                            accum[tree.tag][each.tag]
                        ]
                    accum[tree.tag][each.tag].append(result[each.tag])
                else:
                    accum[tree.tag].update(result)
        else:
            # print(tree.text,tree.items())
            if tree.text is not None and len(tree.items()) != 0:
                for i in tree.items():
                    accum[tree.tag + "-" + i[0]] = i[1]
            #         # print("Trila",i[0],i[1])
            #     # print(tree.tag,)
            #     accum[tree.tag] = tree.text
            else:
                accum[tree.tag] = tree.text

        return accum

    return internal_iter(element_tree, {})
-------------------------------------------------------------
Main.py:
--------------------------------------------------------------

import trial as tr
import xml.etree.ElementTree
from lxml import etree as et
import csv

csv.register_dialect('myDialect', delimiter=',', quoting=csv.QUOTE_NONE)

root = et.parse("20190911_Public01.xml").getroot()

# root = et.parse("testing.xml")
# str_part = et.tostring(root)
# root = et.XML(str_part)

counter = 0
# myFile = open('csvexample3.csv', 'w', newline='')
with open('csvexample3.csv', 'w', newline='') as myFile:
    mydict = dict(enumerate(line.strip() for line in myFile))
    writer = csv.writer(myFile, dialect='myDialect')
# writer.writerows([["ABR", "ABR_recordLastUpdatedDate", "ABR_replaced", "ABN_Number", "ABN_StatusFromDate",
                #    "Entity_Type_IND", "Entitytype_Text", "NonindividualName_Text", "Business_Add_State",
                #    "Business_add_Postcode", "ASIC_Number", "ASICNumber_Type", "GST_Status", "GST_StatusFromDate",
                #    "Other_EntityType", "Other_NonindividualName_Text"]])
# x = root.findall("./ABR")
# print(et.tostring(x))
    count = 0
    # for i in root.findall("./ABR"):
    count += 1
    # str_part = et.tostring(i)
    tree_sort = root.findall('./ABR')
    for i in tree_sort:
        count += 1
        # print(i)
        str_part = et.tostring(i)
        # print(str_part)
        write_dict = tr.make_dict_from_tree(xml.etree.ElementTree.fromstring(str_part))
        try:
            # print(write_dict)
            if write_dict['ABR']['ABN-status'] == 'ACT' and 'MainEntity' in list(write_dict['ABR'].keys()):
                writer.writerows([["ABR" + str(counter), write_dict['ABR-recordLastUpdatedDate'],
                                write_dict['ABR-replaced'], write_dict['ABR']['ABN'],
                                write_dict['ABR']['ABN-ABNStatusFromDate'],
                                write_dict['ABR']['EntityType']['EntityTypeInd'],
                                write_dict['ABR']['EntityType']['EntityTypeText'],
                                write_dict['ABR']['MainEntity']['NonIndividualName']['NonIndividualNameText'],
                                write_dict['ABR']['MainEntity']['BusinessAddress']['AddressDetails']['State'],
                                write_dict['ABR']['MainEntity']['BusinessAddress']['AddressDetails']['Postcode'],
                                write_dict['ABR']['ASICNumber'],
                                write_dict['ABR']['ASICNumber-ASICNumberType'],
                                write_dict['ABR']['GST-status'],
                                write_dict['ABR']['GST-GSTStatusFromDate'],
                                write_dict['ABR']['OtherEntity']['NonIndividualName-type'],
                                write_dict['ABR']['OtherEntity']['NonIndividualName']['NonIndividualNameText']
                                ]])
                counter += 1
            elif write_dict['ABR']['ABN-status'] == 'ACT' and 'LegalEntity' in list(write_dict['ABR'].keys()):
                writer.writerows([["ABR" + str(counter), write_dict['ABR-recordLastUpdatedDate'],
                                write_dict['ABR-replaced'], write_dict['ABR']['ABN'],
                                write_dict['ABR']['ABN-ABNStatusFromDate'],
                                write_dict['ABR']['EntityType']['EntityTypeInd'],
                                write_dict['ABR']['EntityType']['EntityTypeText'],
                                write_dict['ABR']['LegalEntity']['IndividualName-type'],
                                write_dict['ABR']['LegalEntity']['BusinessAddress']['AddressDetails']['State'],
                                write_dict['ABR']['LegalEntity']['BusinessAddress']['AddressDetails']['Postcode'],
                                write_dict['ABR']['ASICNumber'],
                                write_dict['ABR']['ASICNumber-ASICNumberType'],
                                write_dict['ABR']['GST-status'],
                                write_dict['ABR']['GST-GSTStatusFromDate'],
                                write_dict['ABR']['LegalEntity']['IndividualName-type'],
                                write_dict['ABR']['LegalEntity']['IndividualName']['IndividualNameText']
                                ]])
                counter += 1
            elif write_dict['ABR']['ABN-status'] == 'CAN' and 'LegalEntity' in list(write_dict['ABR'].keys()):
                writer.writerows([["ABR" + str(counter), write_dict['ABR-recordLastUpdatedDate'],
                                write_dict['ABR-replaced'], write_dict['ABR']['ABN'],
                                write_dict['ABR']['ABN-ABNStatusFromDate'],
                                write_dict['ABR']['EntityType']['EntityTypeInd'],
                                write_dict['ABR']['EntityType']['EntityTypeText'],
                                write_dict['ABR']['LegalEntity']['IndividualName-type'],
                                write_dict['ABR']['LegalEntity']['BusinessAddress']['AddressDetails']['State'],
                                write_dict['ABR']['LegalEntity']['BusinessAddress']['AddressDetails']['Postcode'],
                                write_dict['ABR']['ASICNumber'],
                                write_dict['ABR']['ASICNumber-ASICNumberType'],
                                "empty", "empty",
                                # write_dict['ABR']['GST-status'],
                                # write_dict['ABR']['GST-GSTStatusFromDate'],
                                write_dict['ABR']['LegalEntity']['IndividualName-type'],
                                write_dict['ABR']['LegalEntity']['IndividualName']['IndividualNameText']
                                ]])
                counter += 1
            elif write_dict['ABR']['ABN-status'] == 'CAN' and 'MainEntity' in list(write_dict['ABR'].keys()):
                writer.writerows([["ABR" + str(counter), write_dict['ABR-recordLastUpdatedDate'],
                                write_dict['ABR-replaced'], write_dict['ABR']['ABN'],
                                write_dict['ABR']['ABN-ABNStatusFromDate'],
                                write_dict['ABR']['EntityType']['EntityTypeInd'],
                                write_dict['ABR']['EntityType']['EntityTypeText'],
                                write_dict['ABR']['MainEntity']['NonIndividualName']['NonIndividualNameText'],
                                write_dict['ABR']['MainEntity']['BusinessAddress']['AddressDetails']['State'],
                                write_dict['ABR']['MainEntity']['BusinessAddress']['AddressDetails']['Postcode'],
                                write_dict['ABR']['ASICNumber'],
                                write_dict['ABR']['ASICNumber-ASICNumberType'],
                                "empty", "empty",
                                # write_dict['ABR']['GST-status'],
                                # write_dict['ABR']['GST-GSTStatusFromDate'],
                                write_dict['ABR']['OtherEntity']['NonIndividualName-type'],
                                write_dict['ABR']['OtherEntity']['NonIndividualName']['NonIndividualNameText']
                                ]])
                counter += 1
        except Exception as e:
            print(e)

    # print(len(write_dict.keys()))

print(count)

Я ожидаю и буду очень признателен за того, кто может помочь мне с получениемв bulkextract.XSD, который находится в том же URL-адресе, который я предоставил, и на который можно ссылаться с помощью приведенной ниже ссылки

https://data.gov.au/dataset/ds-dga-5bd7fcab-e315-42cb-8daf-50b7efc2027e/details

1) Разобрать все атрибуты из XML с использованием схемы XSD, что дает 723 тыс. записейв CSV.И если тег отсутствует, заполните значения как нулевые.Если в каком-либо из тегов XML хранится массив;проанализируйте это как в этих столбцах.

Я хочу выводить, является ли статус ABN ACT, CAN, есть ли номер ASIC или нет, или есть ли какие-либо отсутствующие теги или больше тегов в родительских узлах

...