python-docx
до сих пор не парсит содержимое тегов* w:sdt
, в которых находятся элементы управления содержимым, и не отдает их в "поверхностном" интерфейсе - то есть в содержании paragraphs
и runs
.
Но библиотека использует lxml
для обработки документов и оставляет нам доступ к xml-структуре. Поэтому, следуя совету из тикета на гитхабе, мы, узнав* какие теги и в какой структуре используются нужными нам элементами, можем найти их с помощью xpath
изменить их текст:
from docx import Document
doc = Document('sample_cc_file.docx')
doc_inner = doc._element
target_xpath = '//w:sdt//w:t'
for result_el in doc_inner.xpath(target_xpath):
result_el.text = 'Мы заменили текст!'
doc.save('sample_cc_file 2.docx')
Полный xpath для нашего примера: //w:sdt/w:sdtContent/w:p/w:r/w:t
.
Этот пример не охватывает все виды элементов управления содержимым. Для того, чтобы понять, какой xpath нам придется написать, нужно либо смотреть документацию ooxml, либо вручную смотреть на теги в нужных нам документах, о чем ниже. Исследуя новые для себя элементы, вас будет полезно очищать документы от всего лишнего, чтобы не тратить на поиски много времени.
* Поскольку все "новые" форматы файлов MS Office (docx, pptx) и другого ПО, использующего Office Open XML, это zip-архивы, содержащие определенную структуру xml-файлов, мы всегда можем вручную посмотреть, в каких тегах содержится нужная нам информация, будь то текст, картинки, и пр.: надо просто распаковать файл (например, с помощью 7-zip) и открыть нужную часть файла в текстовом редакторе. Обычно нужная нам информация содержится в word/document.xml
.
Взаимодействовать программно с файлами ooxml можно с помощью zipfile.ZipFile
и привычным для вас xml-парсером (lxml
, Beautiful Soup
и т.д.).