@kdp

Как отсортировать xml список по дате на python?

Есть XML файл того порядка:

<Файл 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">
<ФИО Фамилия="Кир" Имя="Ан" Отчество="Ал"/>
Подписант>
Документ>
Файл>


Нужно отсортировать его по атрибуту ДатаСчФ в порядке возрастания
Предложите как это можно сделать на python?

Я использовал следующий код

#!/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')

выдает

Traceback (most recent call last):
File "./test2.py", line 11, in
sortchildrenby(pokup, 'ДатаСчФ')
File "./test2.py", line 4, in sortchildrenby
parent[:] = sorted(parent, key=lambda child: child.get(attr))
TypeError: unorderable types: NoneType() < NoneType()

UPD: Поправил
  • Вопрос задан
  • 702 просмотра
Решения вопроса 1
valerium
@valerium
Изобретая велосипед
Во-первых, у Вас получился одна лишняя вложенность в цикле. Достаточно написать вот так:
for child in root:
    sortchildrenby(child.iter('СвПокупка'), 'ДатаСчФ')

Функция sorted сама проитерирует последовательность, которую получит на входе.

Во-вторых, просто присваивать в объект ElementTree нельзя, нужно сначала удалить из документа все элементы СвПокупка, потом добавить их заново, в отсортированном виде. Проще всего будет, если переписать Вашу функцию сортировки вот таким макаром:

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)


Соответственно, вызов этой функции из кода будет выглядеть вот так:
for child in root:
    sortchildrenby(child, 'СвПокупка', 'ДатаСчФ')
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы