有没有办法调试 and/or 验证 python-docx 生成的 Microsoft Word 文档 XML?

Is there a way to debug and/or validate Microsoft Word document XML generated by python-docx?

我正在构建一个使用 python-docx 库生成 Microsoft Word 文档报告的简单框架。偶尔,当我生成文档时,我 运行 遇到一个问题,通过 python-docx 成功生成了 docx 文件,但随后 docx 文件将无法在 Microsoft Word 中打开,并出现类似这样的错误消息显示:Microsoft Word 'Unspecified Error' Message

通过逐步完成我的代码 - 逐步将越来越多的内容插入 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...

虽然这行得通,但错误搜寻过程引出了我的问题:有没有办法调试 and/or 验证 python-docx 生成的 Microsoft Word XML 代码?关于验证,有没有一种方法可以验证 python-docx 生成的 docx 文件是否有效,并且能够被 Microsoft Word 打开(实际上不必使用 Word 打开它)?关于调试,有没有一种方法可以让我查看和调试 docx XML 代码以确定问题所在的位置(并且可能获得一些关于 [=30= 中问题产生位置的线索) ] 代码)?这样的工具或方法可能会在我上面描述的错误搜索中为我节省大量时间,并且将来也可能会为我节省时间。非常感谢您的时间和想法。

如您所知,.docx 文件是符合开放打包公约 (OPC) 的 Zip 存档。用 OPC 的说法,这样的存档代表一个 ,其中的每个(主要)文件代表一个 部分

图像等文件是二进制部分,但大部分是XML文档。这些 XML 部分的有效内容由规范随附的一个或多个 XML 架构 (.xsd) 文件指定。这些在 python-docx GitHub 存储库 https://github.com/python-openxml/python-docx/tree/master/ref/xsd.

/ref/xsd/ 文件夹中可用

这些可用于单独验证零件。由于典型的 Word 文件主要是 document.xml 部分,因此大部分里程可能来自验证该部分。

python-docx 使用的相同 lxml 库可用于验证。您应该参考 lxml documentation 了解该过程。

这肯定会捕获架构无效的包部分,但我预计它无法捕获所有可能的 XML 文档,这些文档会在加载到 Word 时导致所谓的 "repair error"。

不过,这可能值得一试。我很想听听它是否发现了上面的错误,我希望这是一个零行和零列 table.