Как получить доступ и заменить текст в определенных абзацах, используя OPENXML powertools для каждого конкретного случая

Я пытаюсь отредактировать некоторые файлы слов, используя C# и openxml. Мне нужно сделать контролируемую замену чисел определенной фразой. Каждый файл слова содержит различное количество информации. Я хочу использовать электроинструменты OPENXML для этой цели.

Я использовал обычный метод openxml для замены, но он очень ненадежный и получает случайные ошибки, такие как ошибка нулевой длины. Я использовал regex replace, и это, кажется, работает, но оно заменяет его из документа, что крайне нежелательно.

Вот небольшой фрагмент кода:

private void redact_Replaceall(string wfile)
        {
            try
            {
                using (WordprocessingDocument doc = WordprocessingDocument.Open(wfile, true))
                {
                    var ydoc = doc.MainDocumentPart.GetXDocument();
                    IEnumerable<XElement> content = ydoc.Descendants(W.body);



                    Regex regex = new Regex(@"\d+\.\d{2,3}");
                    int count1 = OpenXmlPowerTools.OpenXmlRegex.Match(content, regex);


                    int count2 = OpenXmlPowerTools.OpenXmlRegex.Replace(content, regex, replace_text, null);

                    statusBar1.Text = "Try 1: Found: " + count1 + ", Replaced: " + count2;


                    doc.MainDocumentPart.PutXDocument();

                }
            }
            catch(Exception e)
            {
                MessageBox.Show("Replace all exprienced error: " + e.Message);
            }

        }

По сути, я хочу сделать это редактирование на основе содержания пункта. Я могу получить абзацы, используя, но не идентификаторы

IEnumerable<XElement> content = ydoc.Descendants(W.p);

Вот мой подход с использованием обычного метода openxml, но я получаю много ошибок в зависимости от файла.

  foreach (DocumentFormat.OpenXml.Wordprocessing.Paragraph para in bod.Descendants<DocumentFormat.OpenXml.Wordprocessing.Paragraph>())
                                    {

                                        foreach (var run in para.Elements<Run>())
                                        {
                                            foreach (var text in run.Elements<Text>())
                                            {
                                                string temp = text.Text;
                                                int firstlength = first.Length + 1;
                                                int secondlength = second.Length + 1;
                                                if (text.Text.Contains(first) && !(temp.Length > firstlength))
                                                {
                                                    text.Text = text.Text.Replace(first, "DELETED");

                                                }

                                                if (text.Text.Contains(second) && !(temp.Length > secondlength))
                                                {
                                                    text.Text = text.Text.Replace(second, "DELETED");

                                                }
                                            }
                                        }
                                    }

Вот последний новый подход, но я застрял на нем

   private void redact_Replacebadones(string wfile)
        {
            try
            {
                using (WordprocessingDocument doc = WordprocessingDocument.Open(wfile, true))
                {
                    var ydoc = doc.MainDocumentPart.GetXDocument();
                  /*  from XElement xele in ydoc.Root.Elements();
                    List<string> lhsElements = xele.Elements("lhs")
                               .Select(el => el.Attribute("id").Value)
                               .ToList();
                               */
                    /// XElement
                    IEnumerable<XElement> content = ydoc.Descendants(W.p);

                   foreach (var p in content )

                    {
                        if (p.Value.Contains("each") && !p.Value.Contains("DELETED"))
                        {

                            string to_overwrite = p.Value;
                            Regex regexop = new Regex(@"\d+\.\d{2,3}");

                            regexop.Replace(to_overwrite, "Deleted");

                            p.SetValue(to_overwrite);

                            MessageBox.Show("NAME :" + p.GetParagraphInfo() +" VValue:"+to_overwrite);
                        }

                    }


                    doc.MainDocumentPart.PutXDocument();

                }
            }
            catch (Exception e)
            {
                MessageBox.Show("Replace each exprienced error: " + e.Message);
            }

        } 

0 ответов

Может быть немного поздно. В OpenXML Power tools от Эрика Уайта есть функция SearchAndReplace, в которой вы можете заменять текстовое содержимое, поэтому вам не нужно обрабатывать его с помощью RegEx. Эта функция также обрабатывает текст, который разбивается на прогоны. (Если вы редактируете слово, слово может быть разбито на части, так что вы не сможете найти поисковую фразу напрямую.) Может быть, это кому-то поможет.

Другие вопросы по тегам