Skip to content

When there are empty references in a docx document, parsing will throw an error. #170

Description

@glorialucheng

问题

当docx文档里存在空的引用时,解析报错:

Traceback (most recent call last):
  File "D:\miniconda3\Lib\runpy.py", line 198, in _run_module_as_main
    return _run_code(code, main_globals, None,
                     "__main__", mod_spec)
  File "D:\miniconda3\Lib\runpy.py", line 88, in _run_code
    exec(code, run_globals)
    ~~~~^^^^^^^^^^^^^^^^^^^
  File "c:\Users\gloria\.vscode\extensions\ms-python.debugpy-2026.6.0-win32-x64\bundled\libs\debugpy\launcher/../..\debugpy\__main__.py", line 71, in <module>
    cli.main()
    ~~~~~~~~^^
  File "c:\Users\gloria\.vscode\extensions\ms-python.debugpy-2026.6.0-win32-x64\bundled\libs\debugpy\launcher/../..\debugpy/..\debugpy\server\cli.py", line 542, in main
    run()
    ~~~^^
  File "c:\Users\gloria\.vscode\extensions\ms-python.debugpy-2026.6.0-win32-x64\bundled\libs\debugpy\launcher/../..\debugpy/..\debugpy\server\cli.py", line 361, in run_file
    runpy.run_path(target, run_name="__main__")
    ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "c:\Users\gloria\.vscode\extensions\ms-python.debugpy-2026.6.0-win32-x64\bundled\libs\debugpy\_vendored\pydevd\_pydevd_bundle\pydevd_runpy.py", line 310, in run_path
    return _run_module_code(code, init_globals, run_name, pkg_name=pkg_name, script_name=fname)
  File "c:\Users\gloria\.vscode\extensions\ms-python.debugpy-2026.6.0-win32-x64\bundled\libs\debugpy\_vendored\pydevd\_pydevd_bundle\pydevd_runpy.py", line 127, in _run_module_code
    _run_code(code, mod_globals, init_globals, mod_name, mod_spec, pkg_name, script_name)
    ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "c:\Users\gloria\.vscode\extensions\ms-python.debugpy-2026.6.0-win32-x64\bundled\libs\debugpy\_vendored\pydevd\_pydevd_bundle\pydevd_runpy.py", line 118, in _run_code
    exec(code, run_globals)
    ~~~~^^^^^^^^^^^^^^^^^^^
  File "d:\projects\python-mammoth\test.py", line 5, in <module>
    result = mammoth.convert_to_html(docx_file)
  File "d:\projects\python-mammoth\mammoth\__init__.py", line 12, in convert_to_html
    return convert(*args, output_format="html", **kwargs)
  File "d:\projects\python-mammoth\mammoth\__init__.py", line 39, in convert
    return options.read_options(kwargs).bind(lambda convert_options:
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
        docx.read(fileobj, external_file_access=external_file_access).map(transform_document).bind(lambda document:
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ...<5 lines>...
        )
        ^
    )
    ^
  File "d:\projects\python-mammoth\mammoth\results.py", line 15, in bind
    result = func(self.value)
  File "d:\projects\python-mammoth\mammoth\__init__.py", line 40, in <lambda>
    docx.read(fileobj, external_file_access=external_file_access).map(transform_document).bind(lambda document:
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
        conversion.convert_document_element_to_html(
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ...<3 lines>...
        )
        ^
    )
    ^
  File "d:\projects\python-mammoth\mammoth\results.py", line 15, in bind
    result = func(self.value)
  File "d:\projects\python-mammoth\mammoth\__init__.py", line 41, in <lambda>
    conversion.convert_document_element_to_html(
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
        document,
        ^^^^^^^^^
        id_prefix=id_prefix,
        ^^^^^^^^^^^^^^^^^^^^
        **convert_options
        ^^^^^^^^^^^^^^^^^
    )
    ^
  File "d:\projects\python-mammoth\mammoth\conversion.py", line 49, in convert_document_element_to_html
    nodes = converter.visit(element, context)
  File "<string>", line 5, in visit
  File "<string>", line 1, in _accept1
  File "d:\projects\python-mammoth\mammoth\conversion.py", line 83, in visit_document
    nodes = self._visit_all(document.children, context)
  File "d:\projects\python-mammoth\mammoth\conversion.py", line 323, in _visit_all
    for html_node in self.visit(element, context)
                     ~~~~~~~~~~^^^^^^^^^^^^^^^^^^
  File "<string>", line 5, in visit
  File "<string>", line 1, in _accept1
  File "d:\projects\python-mammoth\mammoth\conversion.py", line 106, in visit_paragraph
    return html_path.wrap(children)
           ~~~~~~~~~~~~~~^^^^^^^^^^
  File "d:\projects\python-mammoth\mammoth\html_paths.py", line 33, in wrap
    nodes = generate_nodes()
  File "d:\projects\python-mammoth\mammoth\conversion.py", line 99, in children
    content = self._visit_all(paragraph.children, context)
  File "d:\projects\python-mammoth\mammoth\conversion.py", line 323, in _visit_all
    for html_node in self.visit(element, context)
                     ~~~~~~~~~~^^^^^^^^^^^^^^^^^^
  File "<string>", line 5, in visit
  File "<string>", line 1, in _accept1
  File "d:\projects\python-mammoth\mammoth\conversion.py", line 137, in visit_run
    return nodes()
  File "d:\projects\python-mammoth\mammoth\html_paths.py", line 33, in wrap
    nodes = generate_nodes()
  File "d:\projects\python-mammoth\mammoth\conversion.py", line 110, in <lambda>
    nodes = lambda: self._visit_all(run.children, context)
                    ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^
  File "d:\projects\python-mammoth\mammoth\conversion.py", line 323, in _visit_all
    for html_node in self.visit(element, context)
                     ~~~~~~~~~~^^^^^^^^^^^^^^^^^^
  File "<string>", line 5, in visit
  File "<string>", line 1, in _accept1
  File "d:\projects\python-mammoth\mammoth\conversion.py", line 77, in visit_image
    return self._convert_image(image)
           ~~~~~~~~~~~~~~~~~~~^^^^^^^
  File "d:\projects\python-mammoth\mammoth\images.py", line 12, in convert_image
    attributes.update(func(image))
                      ~~~~^^^^^^^
  File "d:\projects\python-mammoth\mammoth\images.py", line 24, in data_uri
    with image.open() as image_bytes:
         ~~~~~~~~~~^^
  File "d:\projects\python-mammoth\mammoth\docx\body_xml.py", line 593, in open_image
    image_file = docx_file.open(image_path)
  File "d:\projects\python-mammoth\mammoth\zips.py", line 23, in open
    return contextlib.closing(self._zip_file.open(name))
                              ~~~~~~~~~~~~~~~~~~~^^^^^^
  File "D:\miniconda3\Lib\zipfile\__init__.py", line 1652, in open
    zinfo = self.getinfo(name)
  File "D:\miniconda3\Lib\zipfile\__init__.py", line 1580, in getinfo
    raise KeyError(
        'There is no item named %r in the archive' % name)
KeyError: "There is no item named 'word/../NULL' in the archive"

输入的文件由于涉及隐私,因此无法共享,该解压后的docx文件里的 path/to/.docx/word/_rels/document.xml.rels 的内容如下:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships
    xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
    <Relationship Id="rId9" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer" Target="footer2.xml"/>
    <Relationship Id="rId8" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer" Target="footer1.xml"/>
    <Relationship Id="rId7" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/header" Target="header1.xml"/>
    <Relationship Id="rId6" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes" Target="endnotes.xml"/>
    <Relationship Id="rId5" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" Target="footnotes.xml"/>
    <Relationship Id="rId4" Type="http://schemas.microsoft.com/office/2011/relationships/commentsExtended" Target="commentsExtended.xml"/>
    <Relationship Id="rId37" Type="http://schemas.microsoft.com/office/2011/relationships/people" Target="people.xml"/>
    <Relationship Id="rId36" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable" Target="fontTable.xml"/>
    <Relationship Id="rId35" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml" Target="../customXml/item3.xml"/>
    <Relationship Id="rId34" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml" Target="../customXml/item2.xml"/>
    <Relationship Id="rId33" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering" Target="numbering.xml"/>
    <Relationship Id="rId32" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml" Target="../customXml/item1.xml"/>
    <Relationship Id="rId31" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image18.png"/>
    <Relationship Id="rId30" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image17.png"/>
    <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments" Target="comments.xml"/>
    <Relationship Id="rId29" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image16.png"/>
    <Relationship Id="rId28" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image15.png"/>
    <Relationship Id="rId27" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image14.png"/>
    <Relationship Id="rId26" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image13.png"/>
    <Relationship Id="rId25" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image12.png"/>
    <Relationship Id="rId24" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image11.png"/>
    <Relationship Id="rId23" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image10.png"/>
    <Relationship Id="rId22" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image9.png"/>
    <Relationship Id="rId21" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image8.png"/>
    <Relationship Id="rId20" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image7.png"/>
    <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings" Target="settings.xml"/>
    <Relationship Id="rId19" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image6.png"/>
    <Relationship Id="rId18" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image5.png"/>
    <Relationship Id="rId17" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image4.png"/>
    <Relationship Id="rId16" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="../NULL"/>
    <Relationship Id="rId15" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image2.png"/>
    <Relationship Id="rId14" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image1.png"/>
    <Relationship Id="rId13" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="theme/theme1.xml"/>
    <Relationship Id="rId12" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer" Target="footer4.xml"/>
    <Relationship Id="rId11" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/header" Target="header2.xml"/>
    <Relationship Id="rId10" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer" Target="footer3.xml"/>
    <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>
</Relationships>

上面的 <Relationship Id="rId16" ... Target="../NULL"/> 导致的bug。
python-docx也有类似的问题,参考:https://github.com/python-openxml/python-docx/issues/797 and https://github.com/python-openxml/python-docx/issues/1105#issuecomment-1298075246

修复建议

https://github.com/glorialucheng/python-mammoth/commit/9c7f73f5884f06084143ffab5470b403fc9e7ef1

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions