I have a docx file with a certain style and structure and I want to replace some words of that docx file with some other word but I don't want to modify the format of the docx file.
For eg. If I have below mentioned text in docx file in certain font and size
This is used for testing
and I want to replace the word testing with checking. I should get
This is used for checking
With same font style and font size as the word testing
For this, I am trying to modify the xml file of the docx. While checking the xml file it is noticed that docx file divides paragraph text into multiple runs. As denoted below for the text This is used for testing the xml file gives
<w:document
xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas"
xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math"
xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing"
xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"
xmlns:w10="urn:schemas-microsoft-com:office:word"
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml"
xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml"
xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex"
xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup"
xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk"
xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml"
xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 w16se wp14">\n
<w:body>\n
<w:p w:rsidR="00084F90" w:rsidRPr="00B6714F" w:rsidRDefault="00084F90" w:rsidP="00084F90">\n
<w:pPr>\n
<w:rPr>\n
<w:sz w:val="40"/>\n
<w:szCs w:val="40"/>\n
</w:rPr>\n
</w:pPr>\n
<w:r>\n
<w:rPr>\n
<w:b/>\n
<w:bCs/>\n
<w:sz w:val="40"/>\n
<w:szCs w:val="40"/>\n
</w:rPr>\n
<w:t>This is a dock</w:t>\n
</w:r>\n
<w:r w:rsidRPr="00B6714F">\n
<w:rPr>\n
<w:b/>\n
<w:bCs/>\n
<w:sz w:val="40"/>\n
<w:szCs w:val="40"/>\n
</w:rPr>\n
<w:t xml:space="preserve"> document</w:t>\n
</w:r>\n
<w:r w:rsidRPr="00B6714F">\n
<w:rPr>\n
<w:sz w:val="40"/>\n
<w:szCs w:val="40"/>\n
</w:rPr>\n
<w:t>.</w:t>\n
</w:r>\n
</w:p>\n
<w:p w:rsidR="003F4CA3" w:rsidRDefault="00E55BE5" w:rsidP="00084F90">\n
<w:pPr>\n
<w:ind w:left="720" w:firstLine="720"/>\n
</w:pPr>\n
<w:r>\n
<w:rPr>\n
<w:sz w:val="36"/>\n
<w:szCs w:val="36"/>\n
<w:u w:val="single"/>\n
</w:rPr>\n
<w:t xml:space="preserve">It is used </w:t>\n
</w:r>\n
<w:r w:rsidR="00084F90" w:rsidRPr="00B6714F">\n
<w:rPr>\n
<w:sz w:val="36"/>\n
<w:szCs w:val="36"/>\n
<w:u w:val="single"/>\n
</w:rPr>\n
<w:t>for te</w:t>\n
</w:r>\n
<w:r w:rsidR="00084F90">\n
<w:rPr>\n
<w:sz w:val="36"/>\n
<w:szCs w:val="36"/>\n
<w:u w:val="single"/>\n
</w:rPr>\n
<w:t>s</w:t>\n
</w:r>\n
<w:r w:rsidR="00084F90" w:rsidRPr="00B6714F">\n
<w:rPr>\n
<w:sz w:val="36"/>\n
<w:szCs w:val="36"/>\n
<w:u w:val="single"/>\n
</w:rPr>\n
<w:t>ting.</w:t>\n
</w:r>\n
<w:bookmarkStart w:id="0" w:name="_GoBack"/>\n
<w:bookmarkEnd w:id="0"/>\n
</w:p>\n
<w:sectPr w:rsidR="003F4CA3">\n
<w:pgSz w:w="11906" w:h="16838"/>\n
<w:pgMar w:top="1440" w:right="1440" w:bottom="1440" w:left="1440" w:header="708" w:footer="708" w:gutter="0"/>\n
<w:cols w:space="708"/>\n
<w:docGrid w:linePitch="360"/>\n
</w:sectPr>\n
</w:body>\n
</w:document>\n
I want to replace the keys of the dictionary with values like testing with checking and it is getting split into three different runs can be seen in xml file. Is there any way to combine all the splits of the word testing or any general way to overcome this problem.
This is the python code
from lxml import etree
import xml.etree.ElementTree as ET
import zipfile
d = {"dock":"docx","testing":"checking"}
docx_filename = "Test.docx"
def get_word_xml(docx_filename):
zip = zipfile.ZipFile(docx_filename)
xml_content = zip.read('word/document.xml')
return xml_content
def get_xml_tree(xml_string):
return etree.fromstring(xml_string)
xml_string = get_word_xml(docx_filename)
xmltree = get_xml_tree(xml_string)
my_etree = etree.tostring(xmltree, pretty_print=True)
def _check_element_is(element, type_char):
word_schema = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main'
return element.tag == '{%s}%s' % (word_schema,type_char)
e = ET.ElementTree(xmltree)
for elt in e.iter():
if _check_element_is(elt, 't'):
print(elt.text)
The output i'm getting is
This is a dock
document
.
It is used
for te
s
ting.
What i want is
This is a dock document .
It is used for testing.