Есть ли способ отладки и / или проверки XML документа Microsoft Word, созданного с помощью python-docx?

Я создаю простую структуру для создания отчетов по документам Microsoft Word с использованием библиотеки python-docx. Иногда, когда я создаю документ, я сталкиваюсь с проблемой, когда файл docx успешно создается с помощью python-docx, но тогда файл docx не открывается в Microsoft Word и отображается сообщение об ошибке, подобное этому: Сообщение Microsoft Word" Неопределенная ошибка "

Пошагово прорабатывая свой код - постепенно вставляя все больше и больше контента в документ python-docx, а затем пытаясь открыть сгенерированный файл docx после каждого добавления контента - я смог идентифицировать код, который вызывал ошибку. Как оказалось, ошибка возникла, когда я попытался вставить пустой фрейм данных pandas, используя приведенный ниже код:

def insert_as_table(df: pd.DataFrame, document: Document) -> Document:

    # compute parameters
    n_rows = len(df) + 1
    n_cols = len(df.columns)

    # create table object
    table = document.add_table(rows=n_rows, cols=n_cols)

    # fill header cells with text
    for header_cell, col in zip(table.rows[0].cells, df.columns):
        header_cell.text = str(col)

    # fill cells with strings
    for i, row in df.iterrows():
        for table_cell, (j, data) in zip(table.rows[i + 1].cells, row.iteritems()):
            table_cell.text = str(data)

    return document

Мое решение заключалось в добавлении проверки ввода - проверка того, что фрейм данных не пуст, прежде чем пытаться его вставить:

def insert_as_table(df: pd.DataFrame, document: Document) -> Document:

    if df.empty:
        raise ValueError('df is empty. Cannot insert an empty dataframe as a table.')

    etc...

Хотя это сработало, процесс поиска ошибок приводит к моему вопросу: есть ли способ отлаживать и / или проверять XML-код Microsoft Word, сгенерированный python-docx? Что касается проверки, есть ли способ проверить, что файл docx, созданный с помощью python-docx, действителен и может быть открыт в Microsoft Word (без необходимости открывать его с помощью Word)? Что касается отладки, есть ли способ, которым я могу просмотреть и отладить XML-код docx, чтобы определить, где находится проблема (и, возможно, получить некоторые подсказки относительно того, где проблема возникает в коде Python)? Такой инструмент или метод, вероятно, сэкономили бы мне значительное количество времени в поиске ошибок, который я описал выше, и, возможно, также сэкономит мне время в будущем. Большое спасибо за ваше время и мысли.


person Steve    schedule 30.03.2020    source источник


Ответы (1)


Как вы, возможно, знаете, файл .docx - это Zip-архив, соответствующий Open Packaging Convention (OPC). На языке OPC такой архив представляет собой пакет, а каждый из (основных) файлов в нем представляет собой часть.

Такие файлы, как изображения, являются двоичными частями, но большинство частей являются документами XML. Допустимое содержимое этих частей XML определяется одним или несколькими файлами схемы XML (.xsd), которые прилагаются к спецификации. Они доступны в папке /ref/xsd/ репозитория python-docx GitHub https://github.com/python-openxml/python-docx/tree/master/ref/xsd.

Их можно использовать для индивидуальной проверки деталей. Поскольку типичный файл Word - это, в основном, document.xml часть, наибольшая эффективность, вероятно, будет связана с проверкой этого файла.

Та же библиотека lxml, которую использует python-docx, может использоваться для проверки. Для этой процедуры вам следует обратиться к документации по lxml.

Это определенно отловит часть пакета с недопустимой схемой, но я ожидаю, что он не сможет отловить все возможные XML-документы, которые могут вызвать так называемую «ошибку исправления» при загрузке в Word.

Тем не менее, возможно, стоит попробовать. Я хотел бы услышать, обнаружил ли он указанную выше ошибку, которая, как я ожидаю, была таблицей с нулевыми строками и нулевыми столбцами.

person scanny    schedule 31.03.2020
comment
Это очень информативно и определенно помогло мне указать правильное направление. Честно говоря, я понятия не имел, что файл .docx на самом деле является Zip-архивом! Я добился некоторого прогресса в достижении своей цели, но еще не дошел до нее, так как когда я пытаюсь проверить document._element.xml на соответствие файлам .xsd, я получаю etree.XMLSyntaxError, в котором указано Element '{http://schemas.openxmlformats.org/wordprocessingml/2006/main}document': No matching global declaration available for the validation root. (<string>, line 0). Возможно, я что-то упускаю. - person Steve; 02.04.2020
comment
Да, я не думаю, что вы можете проверить строку, созданную document._element.xml; вам нужно перейти непосредственно к байтам части, например document.part.blob, если вы хотите использовать python-docx для навигации по пакету. С этим все еще может быть проблема, но это то, что я попробую в следующий раз. Также вам нужно будет где-то загрузить файл схемы wml.xsd, где, как я ожидаю, находится определение элемента <w:document>. - person scanny; 02.04.2020
comment
Спасибо за подсказку о схеме wml.xsd. После того, как я немного скорректировал этот файл, добавив локальный schemaLocation="xml.xsd" для импорта namespace="http://www.w3.org/XML/1998/namespace", я смог проверить документ xml на его соответствие после того, как я удалил проблемный элемент mc:Ignorable="w14 wp14" из документа xml. В конце концов, оказалось, что документ, содержащий таблицу с нулевыми строками и нулевыми столбцами, будет успешно проверяться на соответствие схеме wml.xsd. Никаких исключений не было. Так что, думаю, я продолжу проверять эти фреймы данных, прежде чем пытаться их вставить. Спасибо еще раз! - person Steve; 03.04.2020