K
K
kdp2015-07-08 18:04:11
Python
kdp, 2015-07-08 18:04:11

How to sort xml list by date in python?

There is an XML file of the order:

<Файл xmlns:xsi="www.w3.org/2001/XMLSchema-instance" ИдФайл="12" ВерсПрог="1С:БУХГАЛТЕРИЯ 7.70.598" ВерсФорм="5.02"ИдФайлИсх="12" ИдФайлПерв="12" КолФайл="1" НомФайл="1">
<Документ КНД="1115122">
<СвПокуп>
<СведЮЛ НаимОрг="ООО "Пром"" ИННЮЛ="1901011441" КПП="4214333001"/>
СвПокуп>
<СвКнПок Период="22" ОтчетГод="2015">
<Всего СумНДСВыч="43.95"/>
СвКнПок>
<СвПокупка НомПП="1" НомерСчФ="1-12" ДатаСчФ="01.04.2015" НаимПрод="ООО "Автоскан"" ИННЮЛ="4203247533" КПП="420501111" СтТовУчНалВсего="1500.00">
<КодВидОпер>01КодВидОпер>
<ДатаПринУчет>01.04.2015ДатаПринУчет>
<СумНДСВыч>
<СумНДС>228.81СумНДС>
СумНДСВыч>
СвПокупка>
<СвПокупка НомПП="2" НомерСчФ="73/1804" ДатаСчФ="02.04.2015" НаимПрод="ООО "Сна"" ИННЮЛ="7711790000" КПП="42" СтТовУчНалВсего="11112.51">
<КодВидОпер>01КодВидОпер>
<ДатаПринУчет>02.04.2015ДатаПринУчет>
<СумНДСВыч>
<СумНДС>1695.13СумНДС>
СумНДСВыч>
СвПокупка>
<СвПокупка НомПП="3" НомерСчФ="135" ДатаСчФ="02.04.2015" НаимПрод="ООО "Вла"" ИННЮЛ="42" КПП="421" СтТовУчНалВсего="2310.00">
<КодВидОпер>01КодВидОпер>
<ДатаПринУчет>02.04.2015ДатаПринУчет>
<СумНДСВыч>
<СумНДС>352.37СумНДС>
СумНДСВыч>
СвПокупка>
<СвПокупка НомПП="5" НомерСчФ="Меж12015131786/27" ДатаСчФ="03.04.2015" НаимПрод="ООО "Р"" ИННЮЛ="54" КПП="42" СтТовУчНалВсего="840.00">
<КодВидОпер>01КодВидОпер>
<ДатаПринУчет>03.04.2015ДатаПринУчет>
<СумНДСВыч>
<СумНДС>128.14СумНДС>
СумНДСВыч>
СвПокупка>
<Подписант ПрПодп="1">
<ФИО Фамилия="Кир" Имя="Ан" Отчество="Ал"/>
Подписант>
Документ>
Файл>

I need to sort it by the DateShF attribute in ascending order.
Suggest how this can be done in python?
I have used the following code
#!/usr/bin/env python3
import xml.etree.ElementTree as ET
def sortchildrenby(parent, attr):
 parent[:] = sorted(parent, key=lambda child: child.get(attr))

tree = ET.parse('12.xml')
root = tree.getroot()
sortchildrenby(root, 'КНД')
for child in root:
 for pokup in child.iter('СвПокупка'):
  sortchildrenby(pokup, 'ДатаСчФ')
tree.write('output.xml', encoding='windows-1251')

produces
Traceback (most recent call last):
File "./test2.py", line 11, in
sortchildrenby(pokup, 'DateSchF')
File "./test2.py", line 4, in sortchildrenby
parent[:] = sorted (parent, key=lambda child: child.get(attr))
TypeError: unorderable types: NoneType() < NoneType()
UPD: Corrected

Answer the question

In order to leave comments, you need to log in

1 answer(s)
V
Valery Ryaboshapko, 2015-07-08
@kdp

First, you have one extra nesting in the loop. It is enough to write like this:

for child in root:
    sortchildrenby(child.iter('СвПокупка'), 'ДатаСчФ')

The sorted function will iterate the sequence it receives as input.
Secondly, it is impossible to simply assign an ElementTree to an object, you must first remove all the SVPurchase elements from the document, then add them again, in a sorted form. The easiest way would be to rewrite your sort function like this:
def sortchildrenby(parent, tag, attr):
    '''функция сортировки элементов XML документа по атрибуту
    :param parent: родительский элемент сортируемых элементов
    :param tag: тэг элементов, которые нужно отсортировать
    :param attr: атрибут, по значению которого будет сортировка
    '''
    sorted_list = sorted(parent.iter(tag), key=lambda child: child.get(attr))

    # Удалеям неотсортированные элементы
    for i in parent.findall(tag):
        parent.remove(i)

    # Добавляем элементы обратно в том порядке, который дала сортировка
    for i in sorted_list:
        parent.append(i)

Accordingly, calling this function from the code will look like this:
for child in root:
    sortchildrenby(child, 'СвПокупка', 'ДатаСчФ')

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question