From e7041cb3e4188c24ca6efbd383df183518d7840d Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Wed, 28 May 2025 19:56:36 +0100 Subject: Ignore AlternateContent elements when there is no Fallback element --- NEWS | 2 ++ mammoth/docx/body_xml.py | 2 +- tests/docx/body_xml_tests.py | 33 +++++++++++++++++++++++---------- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/NEWS b/NEWS index d84dd79..09ae4db 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,8 @@ * Detect checkboxes, both as complex fields and structured document tags, and convert them to checkbox inputs. +* Ignore AlternateContent elements when there is no Fallback element. + # 1.8.0 * Add style mapping for highlights. diff --git a/mammoth/docx/body_xml.py b/mammoth/docx/body_xml.py index cc4e9ad..40b5f9d 100644 --- a/mammoth/docx/body_xml.py +++ b/mammoth/docx/body_xml.py @@ -569,7 +569,7 @@ def _create_reader(numbering, content_types, relationships, styles, docx_file, f return _success(documents.comment_reference(element.attributes["w:id"])) def alternate_content(element): - return read_child_elements(element.find_child("mc:Fallback")) + return read_child_elements(element.find_child_or_null("mc:Fallback")) def read_sdt(element): checkbox = element.find_child_or_null("w:sdtPr").find_child("wordml:checkbox") diff --git a/tests/docx/body_xml_tests.py b/tests/docx/body_xml_tests.py index 8a8f40b..424c2f5 100644 --- a/tests/docx/body_xml_tests.py +++ b/tests/docx/body_xml_tests.py @@ -1406,17 +1406,30 @@ def test_text_boxes_have_content_appended_after_containing_paragraph(): result = _read_and_get_document_xml_elements(paragraph) assert_equal(result[1].style_id, "textbox-content") -def test_alternate_content_is_read_using_fallback(): - element = xml_element("mc:AlternateContent", {}, [ - xml_element("mc:Choice", {"Requires": "wps"}, [ - _paragraph_with_style_id("first") - ]), - xml_element("mc:Fallback", {}, [ - _paragraph_with_style_id("second") + +class AlternateContentTests(object): + def test_when_fallback_is_present_then_fallback_is_read(self): + element = xml_element("mc:AlternateContent", {}, [ + xml_element("mc:Choice", {"Requires": "wps"}, [ + _paragraph_with_style_id("first") + ]), + xml_element("mc:Fallback", {}, [ + _paragraph_with_style_id("second") + ]) ]) - ]) - result = _read_and_get_document_xml_element(element) - assert_equal("second", result.style_id) + result = _read_and_get_document_xml_element(element) + assert_equal("second", result.style_id) + + + def test_when_fallback_is_not_present_then_element_is_ignored(self): + element = xml_element("mc:AlternateContent", {}, [ + xml_element("mc:Choice", {"Requires": "wps"}, [ + _paragraph_with_style_id("first") + ]), + ]) + result = _read_and_get_document_xml_elements(element) + assert_equal([], result) + def test_sdt_is_read_using_sdt_content(): element = xml_element("w:sdt", {}, [ -- cgit v1.2.3