Проверка на пустые элементы в XML

Есть xml файл:

<row>
<row_id>11</row_id>
<col_account_id>2783</col_account_id>
<col_login>unknown</col_login>
<col_full_name>unknown</col_full_name>
<col_actual_payment_date>Tue Jul 13 14:08:35 MSK 2021</col_actual_payment_date>
<col_date_of_payment>Tue Jul 13 14:09:01 MSK 2021</col_date_of_payment>
<col_volume>9.500</col_volume>
<col_currency>BYN</col_currency>
<col_comment>Ошибочно начисленная абон. плата</col_comment>
<col_payment_method>Перерасчет (103)</col_payment_method>
<col_recieved_by>evandrushenko (-44)</col_recieved_by>
</row>
<row>
<row_id>12</row_id>
<col_account_id></col_account_id>
<col_login>ubil1_20</col_login>
<col_full_name>(РОУТ)Демидова Наталья Васильевна</col_full_name>
<col_actual_payment_date>Tue Jul 13 10:00:03 MSK 2021</col_actual_payment_date>
<col_date_of_payment>Tue Jul 13 10:00:31 MSK 2021</col_date_of_payment>
<col_volume>15.900</col_volume>
<col_currency>BYN</col_currency>
<col_comment>No comment</col_comment>
<col_payment_method>Оплата наличными (абон плата при подкл) (108)</col_payment_method>
<col_recieved_by>evandrushenko (-44)</col_recieved_by>
</row>
<row>
<row_id>13</row_id>
<col_account_id>2784</col_account_id>
<col_login>chong8_25-2</col_login>
<col_full_name>(РОУТ )Новиков Александр Владимирович</col_full_name>
<col_actual_payment_date>Fri Jul 09 12:00:26 MSK 2021</col_actual_payment_date>
<col_date_of_payment>Fri Jul 09 12:00:43 MSK 2021</col_date_of_payment>
<col_volume>12.900</col_volume>
<col_currency>BYN</col_currency>
<col_comment></col_comment>
<col_payment_method>Оплата наличными (абон плата при подкл) (108)</col_payment_method>
<col_recieved_by>evandrushenko (-44)</col_recieved_by>
</row>

Есть парсер для XML файла:

import xml.dom.minidom as minidom

try:
        with minidom.parse(xml) as doc:
            books = doc.getElementsByTagName("row")

            xml_tuple = ("col_date_of_payment", "col_actual_payment_date", "col_account_id",\
                         "col_full_name", "col_volume", "col_comment", "col_payment_method")
            titles = []
            [[titles.append(book.getElementsByTagName(i)[0]) for i in xml_tuple] \
                                                             for book in books]
            """Поля не должны быть пустыми"""
            y = []
            [[y.append(node.data) for node in title.childNodes \
                                                               if node.nodeType == node.TEXT_NODE]\
                                  for title in titles]
    except (Exception, TypeError, AttributeError):
        log.error("Exception occurred", exc_info=True)
        time.sleep(20)
    else:
        log.info("Считаем количество платежей")
        y = zip(*[iter(y)] * 7)
        yield tuple(y)

Как здесь можно реализовать проверку на пустые поля?

Скажем, если col_actual_payment_date пустой, то заполнить это поле звездочками(***).

Результат должен быть следующий:

[['Tue Jul 13 14:09:01 MSK 2021', 'Tue Jul 13 14:08:35 MSK 2021', '2783', 'unknown', '9.500', 'Ошибочно начисленная абон. плата', 'Перерасчет (103)'],
['16.07.2021', '16.07.2021', '***', '(РОУТ)Демидова Наталья Васильевна', '14,97', 'Перенос с СКТ на СПД Справка №56 от 13.07.2021', 'Оплата наличными (абон плата при подкл) (108)'],
['Fri Jul 09 12:00:43 MSK 2021', 'Fri Jul 09 12:00:26 MSK 2021', '2784', '(РОУТ )Новиков Александр Владимирович', '12.900', '***', 'Оплата наличными (абон плата при подкл) (108)']]

Ответы (1 шт):

Автор решения: gil9red

Добавил функцию для получения текста из элемента с значением по умолчанию

Переписал алгоритм парсинга

Пример:

import xml.dom.minidom as minidom


def get_all_text(node) -> str:
    if node.nodeType == node.TEXT_NODE:
        return node.data
    else:
        return ''.join(get_all_text(child_node) for child_node in node.childNodes)


xml = '1.xml'

with minidom.parse(xml) as doc:
    xml_tuple = (
        "col_date_of_payment", "col_actual_payment_date", "col_account_id",
        "col_full_name", "col_volume", "col_comment", "col_payment_method"
    )

    items = []
    for row_el in doc.getElementsByTagName("row"):
        row = []
        for tag_name in xml_tuple:
            child_el = row_el.getElementsByTagName(tag_name)[0]
            child_text = get_all_text(child_el) or '***'
            row.append(child_text)

        items.append(row)

    print(items)

Результат:

[
['Tue Jul 13 14:09:01 MSK 2021', 'Tue Jul 13 14:08:35 MSK 2021', '2783', 'unknown', '9.500', 'Ошибочно начисленная абон. плата', 'Перерасчет (103)'], 
['Tue Jul 13 10:00:31 MSK 2021', 'Tue Jul 13 10:00:03 MSK 2021', '***', '(РОУТ)Демидова Наталья Васильевна', '15.900', 'No comment', 'Оплата наличными (абон плата при подкл) (108)'], 
['Fri Jul 09 12:00:43 MSK 2021', 'Fri Jul 09 12:00:26 MSK 2021', '2784', '(РОУТ )Новиков Александр Владимирович', '12.900', '***', 'Оплата наличными (абон плата при подкл) (108)']
]

UPD.

Думаю, указывать *** в функции в качестве значения по умолчанию нехорошая идея, лучше вынести проверку из функции:

def get_all_text(node) -> str:
    if node.nodeType == node.TEXT_NODE:
        return node.data
    else:
        return ''.join(get_all_text(child_node) for child_node in node.childNodes)

with minidom.parse(xml) as doc:
    ...
    for row_el in doc.getElementsByTagName("row"):
         ...
            child_text = get_all_text(child_el) or '***'
→ Ссылка