Replace text in a Word document using streaming XML
Streaming replacement is useful for large documents because the main document XML can be processed without loading a full model in memory.
The tradeoff is the same as other large-part workflows: a DOM-style reader is easier to query and edit, but it materializes the part; a streaming reader processes XML forward-only and can use much less memory.
Rust workflow
Open the main document part, stream across text elements, and replace matches inside each w:t value:
#![allow(unused)] fn main() { pub fn replace_text_in_main_document( path: &Path, search: &str, replacement: &str, ) -> Result<Vec<u8>, Box<dyn std::error::Error>> { let mut document = WordprocessingDocument::new_from_file_with_settings(path, lazy_settings())?; let main_part = document.main_document_part()?; let document_xml = main_part.data_as_str(&document)?.unwrap_or_default(); let updated_xml = replace_text_values(document_xml, search, replacement); main_part.set_data(&mut document, updated_xml.into_bytes())?; let mut buffer = Cursor::new(Vec::new()); document.save(&mut buffer)?; Ok(buffer.into_inner()) } }
The upstream streaming pattern reads the main document part and writes updated XML to a separate in-memory stream, then replaces the original part after both reader and writer are closed. This avoids opening the same part for simultaneous read and write streams.
Text in a Word document can be split across multiple w:t elements. Single-word replacement is straightforward; phrase replacement needs a buffering strategy that spans runs while preserving run properties.