YASR - еще один вопрос поиска и замены
Окружение: asp.net C# openxml
Итак, я читал тонну фрагментов и пытался воссоздать колесо, но я надеюсь, что сомоне поможет мне быстрее добраться до места назначения. У меня есть несколько документов, которые мне нужно объединить... проверить... Я могу сделать это с OpenXML SDK. Птицы поют, солнце до сих пор светит. Теперь, когда у меня есть документ так, как я хочу, мне нужно искать и заменять текст и / или элементы управления контентом.
Я попытался использовать свой собственный текст - {заменить это}, но когда я смотрю на xml (переименуйте docx в zip и просмотрите файл), {не находится рядом с текстом. Поэтому мне либо нужно знать, как защитить это внутри элемента, чтобы они не расходились, либо мне нужно найти другой способ поиска и замены.
Я могу искать / заменять, если это XML-файл, но потом я возвращаюсь к тому, что не могу легко комбинировать элементы.
Код ниже... и как я уже говорил... слияние документов работает нормально... просто нужно заменить вещи.
* Обновить * изменил мой вызов замены, чтобы идти после тега вместо регулярного выражения. У меня сейчас правильная информация, но вызов.Replace, похоже, не работает. Последние четыре строки предназначены для проверки того, что я видел правильное содержимое тега. Я просто хочу заменить это содержимое сейчас.
protected void exeProcessTheDoc(object sender, EventArgs e)
{
string doc1 = Server.MapPath("~/Templates/doc1.docx");
string doc2 = Server.MapPath("~/Templates/doc2.docx");
string final_doc = Server.MapPath("~/Templates/extFinal.docx");
File.Delete(final_doc);
File.Copy(doc1, final_doc);
using (WordprocessingDocument myDoc = WordprocessingDocument.Open(final_doc, true))
{
string altChunkId = "AltChunkId2";
MainDocumentPart mainPart = myDoc.MainDocumentPart;
AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(
AlternativeFormatImportPartType.WordprocessingML, altChunkId);
using (FileStream fileStream = File.Open(doc2, FileMode.Open))
chunk.FeedData(fileStream);
AltChunk altChunk = new AltChunk();
altChunk.Id = altChunkId;
mainPart.Document.Body.InsertAfter(altChunk, mainPart.Document.Body.Elements<Paragraph>().Last());
mainPart.Document.Save();
}
exeSearchReplace(final_doc);
}
public static void GetPropertyFromDocument(string document, string outdoc)
{
XmlDocument xmlProperties = new XmlDocument();
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(document, false))
{
ExtendedFilePropertiesPart appPart = wordDoc.ExtendedFilePropertiesPart;
xmlProperties.Load(appPart.GetStream());
}
XmlNodeList chars = xmlProperties.GetElementsByTagName("Company");
chars.Item(0).InnerText.Replace("{ClientName}", "Penn Inc.");
StreamWriter sw;
sw = File.CreateText(outdoc);
sw.WriteLine(chars.Item(0).InnerText);
sw.Close();
}
}
}
2 ответа
Если вы хотите найти и заменить текст в документе WordprocessingML, есть довольно простой алгоритм, который вы можете использовать:
- Разбейте все пробеги в серии одного персонажа. Это включает в себя прогоны, которые имеют специальные символы, такие как разрыв строки, возврат каретки или жесткий табуляция.
- Тогда довольно легко найти набор прогонов, которые соответствуют символам в строке поиска.
- После того как вы определили набор прогонов, которые совпадают, вы можете заменить этот набор прогонов на вновь созданный прогон (в котором есть свойства прогона, содержащие первый символ, соответствующий строке поиска).
- После замены односимвольных прогонов на вновь созданный прогон можно объединить смежные прогоны с одинаковым форматированием.
Я написал пост в блоге и записал скриншот, который проходит по этому алгоритму.
Сообщение в блоге: http://openxmldeveloper.org/archive/2011/05/12/148357.aspx
Снимок экрана: http://www.youtube.com/watch?v=w128hJUu3GM
-Эрик
Если я правильно читаю, у вас есть что-то вроде "{replace me}" в.docx, а затем, когда вы перебираете XML, вы находите такие вещи, как <t>{replace</t><t> me</><t>}</t>
или какой-то такой хаос. Теперь, с таким XML, невозможно создать подпрограмму, которая заменит "{replace me}".
Если это так, то это очень, очень вероятно, связано с тем, что это считается ошибкой проверки. то есть это неправильно написано, что касается Word. Причина в том, что вы открыли документ в Word и включили проверку. Таким образом, текст помечается как "isDirty" и разбивается на разные серии.
Два способа исправить это:
- Сторона клиента. В Word просто убедитесь, что все ошибки проверки корректируются или игнорируются.
- Формат сторона. Используйте инструмент MarkupSimplifier, являющийся частью Power Tool редактора пакетов XML для Visual Studio 2010, чтобы исправить это за пределами клиента. У Эрика Уайта есть отличная (и своевременная для вас - всего несколько дней) статья: Начало работы с Open XML Упрощение разметки PowerTools