Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Thema wird gezeigt, wie Sie das Open XML SDK verwenden, um Text in einem Word Dokument mithilfe des SAX-Ansatzes (Simple API for XML) durch das Open XML SDK zu suchen und zu ersetzen. Weitere Informationen zur grundlegenden Struktur eines WordprocessingML
Dokuments finden Sie unter Struktur eines WordprocessingML-Dokuments.
Gründe für die Verwendung des SAX-Ansatzes
Das Open XML SDK bietet zwei Möglichkeiten zum Analysieren von Office Open XML-Dateien: das Dokumentobjektmodell (DOM) und die Simple API for XML (SAX). Der DOM-Ansatz wurde entwickelt, um das Abfragen und Analysieren von Open XML-Dateien mithilfe von stark typisierten Klassen zu vereinfachen. Der DOM-Ansatz erfordert jedoch das Laden ganzer Open XML-Teile in den Arbeitsspeicher, was bei der Arbeit mit sehr großen Teilen zu einer langsameren Verarbeitung und Zu wenig Arbeitsspeicher führen kann. Der SAX-Ansatz liest den XML-Code in einem Open XML-Teil elementweise ein, ohne den gesamten Teil in den Arbeitsspeicher zu lesen, sodass nicht zwischengespeicherter Vorwärtszugriff auf die XML-Daten ermöglicht wird. Dies macht es zu einer besseren Wahl beim Lesen sehr großer Teile.
Zugreifen auf MainDocumentPart
Der Text eines Word Dokuments wird im MainDocumentPartgespeichert, sodass der erste Schritt zum Suchen und Ersetzen von Text darin besteht, auf die Word Dokument MainDocumentPart
zuzugreifen. Dazu verwenden wir zunächst die WordprocessingDocument.Open
-Methode, die den Pfad zum Dokument als ersten Parameter übergibt, und einen zweiten Parameter true
, um anzugeben, dass die Datei zur Bearbeitung geöffnet wird. Stellen Sie dann sicher, dass nicht MainDocumentPart
NULL ist.
// Open the WordprocessingDocument for editing
using (WordprocessingDocument wordprocessingDocument = WordprocessingDocument.Open(path, true))
{
// Access the MainDocumentPart and make sure it is not null
MainDocumentPart? mainDocumentPart = wordprocessingDocument.MainDocumentPart;
if (mainDocumentPart is not null)
Erstellen von Memory Stream, OpenXmlReader und OpenXmlWriter
Beim DOM-Ansatz zum Bearbeiten von Dokumenten wird der gesamte Teil in den Arbeitsspeicher eingelesen, sodass wir die stark typisierten Klassen des Open XML SDK verwenden können, um auf die Text Klasse zuzugreifen, um auf den Text des Dokuments zuzugreifen und ihn zu bearbeiten. Der SAX-Ansatz verwendet jedoch die OpenXmlPartReader Klassen und OpenXmlPartWriter , die mit vorwärtsgerichtetem Zugriff auf den Datenstrom eines Teils zugreifen. Dies hat den Vorteil, dass das gesamte Teil nicht in den Arbeitsspeicher geladen werden muss, was schneller ist und weniger Arbeitsspeicher verwendet. Da derselbe Teil jedoch nicht in mehreren Streams gleichzeitig geöffnet werden kann, können wir keine erstellen OpenXmlReader , um einen Teil zu lesen, und ein OpenXmlWriter , um denselben Teil gleichzeitig zu bearbeiten. Die Lösung hierfür besteht darin, einen zusätzlichen Speicherdatenstrom zu erstellen und den aktualisierten Teil in den neuen Speicherdatenstrom zu schreiben und dann den Stream zu verwenden, um den Teil zu aktualisieren, wenn OpenXmlReader
und OpenXmlWriter
verworfen wurden. Im folgenden Code erstellen wir die MemoryStream
, um den aktualisierten Teil zu speichern, und erstellen eine OpenXmlReader
für die MainDocumentPart
und eine OpenXmlWriter
, um in die MemoryStream
// Create a MemoryStream to store the updated MainDocumentPart
using (MemoryStream memoryStream = new MemoryStream())
{
// Create an OpenXmlReader to read the main document part
// and an OpenXmlWriter to write to the MemoryStream
using (OpenXmlReader reader = OpenXmlPartReader.Create(mainDocumentPart))
using (OpenXmlWriter writer = OpenXmlPartWriter.Create(memoryStream))
Lesen des Teils und Schreiben in die neue Stream
Da wir nun einen OpenXmlReader
haben, um den Teil zu lesen, und ein OpenXmlWriter
, um in das neue MemoryStream
zu schreiben, verwenden wir die Read -Methode, um jedes Element im Teil zu lesen. Wenn jedes Element gelesen wird, überprüfen wir, ob es vom Typ ist, und wenn dies der Wert Text
ist, verwenden wir die <xrefDocumentFormat.OpenXml.OpenXmlReader.GetText*-> Methode, um auf den Text zuzugreifen und Replace den Text zu aktualisieren. Wenn es sich nicht um ein Text
Element handelt, wird es unverändert in den Stream geschrieben.
Hinweis
In einem Word Dokumenttext in mehrere Text
Elemente unterteilt werden kann. Wenn Sie also einen Ausdruck und nicht ein einzelnes Wort ersetzen, empfiehlt es sich, jeweils ein Wort zu ersetzen.
// Write the XML declaration with the version "1.0".
writer.WriteStartDocument();
// Read the elements from the MainDocumentPart
while (reader.Read())
{
// Check if the element is of type Text
if (reader.ElementType == typeof(Text))
{
// If it is the start of an element write the start element and the updated text
if (reader.IsStartElement)
{
writer.WriteStartElement(reader);
string text = reader.GetText().Replace(textToReplace, replacementText);
writer.WriteString(text);
}
else
{
// Close the element
writer.WriteEndElement();
}
}
else
// Write the other XML elements without editing
{
if (reader.IsStartElement)
{
writer.WriteStartElement(reader);
}
else if (reader.IsEndElement)
{
writer.WriteEndElement();
}
}
}
Schreiben der neuen Stream in MainDocumentPart
Wenn der aktualisierte Teil in den Speicherstream geschrieben wird, besteht der letzte Schritt darin, die Position von MemoryStream
auf 0 festzulegen und die FeedData -Methode zu verwenden, um den MainDocumentPart
durch den aktualisierten Stream zu ersetzen.
// Set the MemoryStream's position to 0 and replace the MainDocumentPart
memoryStream.Position = 0;
mainDocumentPart.FeedData(memoryStream);
Beispielcode
Im Folgenden finden Sie den vollständigen Beispielcode zum Ersetzen von Text in einem Word Dokument mithilfe des SAX-Ansatzes (Simple API for XML).
void ReplaceTextWithSAX(string path, string textToReplace, string replacementText)
{
// Open the WordprocessingDocument for editing
using (WordprocessingDocument wordprocessingDocument = WordprocessingDocument.Open(path, true))
{
// Access the MainDocumentPart and make sure it is not null
MainDocumentPart? mainDocumentPart = wordprocessingDocument.MainDocumentPart;
if (mainDocumentPart is not null)
{
// Create a MemoryStream to store the updated MainDocumentPart
using (MemoryStream memoryStream = new MemoryStream())
{
// Create an OpenXmlReader to read the main document part
// and an OpenXmlWriter to write to the MemoryStream
using (OpenXmlReader reader = OpenXmlPartReader.Create(mainDocumentPart))
using (OpenXmlWriter writer = OpenXmlPartWriter.Create(memoryStream))
{
// Write the XML declaration with the version "1.0".
writer.WriteStartDocument();
// Read the elements from the MainDocumentPart
while (reader.Read())
{
// Check if the element is of type Text
if (reader.ElementType == typeof(Text))
{
// If it is the start of an element write the start element and the updated text
if (reader.IsStartElement)
{
writer.WriteStartElement(reader);
string text = reader.GetText().Replace(textToReplace, replacementText);
writer.WriteString(text);
}
else
{
// Close the element
writer.WriteEndElement();
}
}
else
// Write the other XML elements without editing
{
if (reader.IsStartElement)
{
writer.WriteStartElement(reader);
}
else if (reader.IsEndElement)
{
writer.WriteEndElement();
}
}
}
}
// Set the MemoryStream's position to 0 and replace the MainDocumentPart
memoryStream.Position = 0;
mainDocumentPart.FeedData(memoryStream);
}
}
}
}