В целях модульного тестирования я хочу проверить, соответствует ли XML, созданный для абзаца Word, тому, что я ожидаю при разборе абзаца HTML.
Как извлечь сам XML вместо записи в файл, распаковки файла и повторного чтения содержащегося в нем файла word/document.xml?
например
from docx import Document
import bs4
def add_parsed_html_to_paragraph(p, s):
soup = bs4.BeautifulSoup(s)
para = soup.find('p')
for e in para.children:
if type(e) == bs4.element.NavigableString:
r = p.add_run(str(e))
else:
r = p.add_run(e.text)
if e.name == 'sub':
r.font.subscript = True
elif e.name == 'sup':
r.font.superscript = True
title = 'A formula: H<sub>2</sub>O.'
document = Document()
p = document.add_paragraph()
add_parsed_html_to_paragraph(p, title)
# ... Now I want to check p or document for the correct XML
Каждый так называемый объект элемента oxml
в python-docx
имеет свойство .xml
именно для этого варианта использования. Он используется для внутренних модульных тестов.
Все, что вам нужно, это доступ к внутренней переменной, используемой для элемента XML, которая обычно доступна, если щелкнуть ссылку [source]
рядом с этим объектом в документах, например здесь: https://python-docx.readthedocs.io/en/latest/api/text.html#paragraph-objects
Перейдя по этой ссылке, вы обнаружите, что для абзаца базовый элемент XML доступен на ._p
. Обычно это тэг элемента без префикса пространства имен, хотя иногда это общий ._element
. Этот последний вариант хорош, чтобы попробовать его в крайнем случае, если вам нужно угадать.
Таким образом, использовать его так же просто, как:
>>> paragraph._p.xml
<w:p>
<w:pPr>
<w:jc w:val = "right"/>
</w:pPr>
<w:r>
<w:t>Right-aligned</w:t>
</w:r>
</w:p>
В утилитах модульного тестирования есть сопутствующий предметно-ориентированный язык (DSL) под названием CXML (compact XML), который позволяет вам позаботиться о пространстве имен, что в противном случае является большой проблемой. Это выглядит примерно так:
expected_xml = cxml.xml('w:p(w:pPr/w:jc{w:val=right},w:r/w:t"Right-aligned")')
Вы можете увидеть примеры в модульных тестах, например здесь: https://github.com/python-openxml/python-docx/blob/master/tests/text/test_paragraph.py#L113, и задать более конкретные вопросы здесь с тегом «python-docx», если вам нужна помощь.