diff --git a/packages/markitdown/src/markitdown/converters/_epub_converter.py b/packages/markitdown/src/markitdown/converters/_epub_converter.py index 82b01e25a..3cd13d24d 100644 --- a/packages/markitdown/src/markitdown/converters/_epub_converter.py +++ b/packages/markitdown/src/markitdown/converters/_epub_converter.py @@ -141,6 +141,17 @@ def _get_all_texts_from_nodes(self, dom: Document, tag_name: str) -> List[str]: """Helper function to extract all occurrences of a tag (e.g., multiple authors).""" texts: List[str] = [] for node in dom.getElementsByTagName(tag_name): - if node.firstChild and hasattr(node.firstChild, "nodeValue"): - texts.append(node.firstChild.nodeValue.strip()) + text_parts: List[str] = [] + self._collect_node_text(node, text_parts) + text_val = "".join(text_parts).strip() + if text_val: + texts.append(text_val) return texts + + def _collect_node_text(self, node: Any, text_parts: List[str]) -> None: + """Recursively collect text node values from a DOM node.""" + for child in node.childNodes: + if child.nodeValue: + text_parts.append(child.nodeValue) + elif child.hasChildNodes(): + self._collect_node_text(child, text_parts) diff --git a/packages/markitdown/tests/test_module_misc.py b/packages/markitdown/tests/test_module_misc.py index f966eee1e..065041b49 100644 --- a/packages/markitdown/tests/test_module_misc.py +++ b/packages/markitdown/tests/test_module_misc.py @@ -587,6 +587,36 @@ def test_markitdown_llm() -> None: validate_strings(result, PPTX_TEST_STRINGS) +def test_epub_metadata_nodevalue(): + from defusedxml.minidom import parseString + from markitdown.converters._epub_converter import EpubConverter + + xml_data = ( + '' + "Structured Title" + "Author 1" + "Author 2" + "" + "" + "" + ) + dom = parseString(xml_data) + converter = EpubConverter() + + title = converter._get_text_from_node(dom, "dc:title") + assert title == "Structured Title" + + creators = converter._get_all_texts_from_nodes(dom, "dc:creator") + assert creators == ["Author 1", "Author 2"] + + publisher = converter._get_text_from_node(dom, "dc:publisher") + assert publisher is None + + missing = converter._get_text_from_node(dom, "dc:date") + assert missing is None + + + if __name__ == "__main__": """Runs this file's tests from the command line.""" for test in [ @@ -602,6 +632,7 @@ def test_markitdown_llm() -> None: test_markitdown_exiftool, test_markitdown_llm_parameters, test_markitdown_llm, + test_epub_metadata_nodevalue, ]: print(f"Running {test.__name__}...", end="") test()