3

看看这篇文章的结尾,除了文本框的问题!

使用这种方法,我想打开一个文档,替换一些文本,然后不理会它。它有效,这是值得骄傲的事情。:D

public static void replaceInOpenXMLDocument(string pfad, string zuErsetzen, string neuerString)
        {
            using (WordprocessingDocument doc = WordprocessingDocument.Open(pfad, true))
            {
                var res = from bm in doc.MainDocumentPart.Document.Body.Descendants()
                          where bm.InnerText != string.Empty && bm.InnerText.Contains(zuErsetzen) && bm.HasChildren == false
                          select bm;

                foreach (var item in res)
                {
                    item.InsertAfterSelf(new Text(item.InnerText.Replace(zuErsetzen, neuerString)));
                    item.Remove();
                }
                doc.Close();
            }
        }

但它只适用于没有特殊字符的替换。例如:

操作系统将被替换为Windows 9000 以上

[OS]将保持原样。

情况1:

在文档中:

您将 os 用于任何目的。

replaceInOpenXMLDocument("C:\NSA\suspects.docx", "os", "Win 2000");

将导致:

无论您有什么目的,您都可以使用 Win 2000。

案例二:

带有特殊字符...

您将 [os] 用于任何目的。

replaceInOpenXMLDocument("C:\NSA\suspects.docx", "[os]", "Win 2000");

...它只是忽略了我:

您将 [os] 用于任何目的。

我尝试了几个特殊字符()[]{}等,但它们从未被替换。

有什么我忘了做的吗?或者它根本无法用这种方法替换特殊字符?如果是这样,我只需要一个简单的解决方法。

有没有人可以帮我解决我的绝望?:)

解决方案/补充1:

感谢Flowerking!这是我现在正在使用的代码:

public static void replaceInOpenXMLDocument(string pfad, string zuErsetzen, string neuerString)
        {
            using (WordprocessingDocument doc = WordprocessingDocument.Open(pfad, true))
            {
                SimplifyMarkupSettings settings = new SimplifyMarkupSettings
                {
                    NormalizeXml = true, // Merges Run's in a paragraph with similar formatting

                };
                MarkupSimplifier.SimplifyMarkup(doc, settings);

                //zuErsetzen = new XElement("Name", zuErsetzen).Value;
                var res = from bm in doc.MainDocumentPart.Document.Body.Descendants()
                          where bm.InnerText != string.Empty && bm.InnerText.Contains(zuErsetzen) && bm.HasChildren == false
                          select bm;
                // bm.InnerText.Contains(zuErsetzen)

                foreach (var item in res)
                {
                    item.InsertAfterSelf(new Text(item.InnerText.Replace(zuErsetzen, neuerString)));
                    item.Remove();
                }

                doc.Close();
            }
        }

(此代码适用于其中包含普通文本的普通文档!)

解决方案/补充 2: 如果你想替换文本框中的文本,我不得不做一些解决方法。文本框被声明为图片,所以上面的代码不会触及它。

我发现了一个额外的类(链接),甚至可以通过文本框进行搜索。ZIP 下载包含一个示例程序,易于理解。

4

1 回答 1

4

发生这种情况是因为 Open XML 词通常在包含特殊字符的文本时创建,可能如下所示:

  <w:r w:rsidRPr="00316587">
    <w:rPr>
      <w:rFonts w:ascii="Consolas" w:hAnsi="Consolas" w:eastAsia="Times New Roman" w:cs="Consolas" />
      <w:color w:val="823125" />
      <w:sz w:val="20" />
      <w:szCs w:val="20" />
      <w:lang w:eastAsia="en-GB" />
    </w:rPr>
    <w:t>[</w:t>
  </w:r>
  <w:proofErr w:type="gramStart" />
  <w:r w:rsidRPr="00316587">
    <w:rPr>
      <w:rFonts w:ascii="Consolas" w:hAnsi="Consolas" w:eastAsia="Times New Roman" w:cs="Consolas" />
      <w:color w:val="823125" />
      <w:sz w:val="20" />
      <w:szCs w:val="20" />
      <w:lang w:eastAsia="en-GB" />
    </w:rPr>
    <w:t>text-to-replace</w:t>
  </w:r>
  <w:proofErr w:type="gramEnd" />
  <w:r w:rsidRPr="00316587">
    <w:rPr>
      <w:rFonts w:ascii="Consolas" w:hAnsi="Consolas" w:eastAsia="Times New Roman" w:cs="Consolas" />
      <w:color w:val="823125" />
      <w:sz w:val="20" />
      <w:szCs w:val="20" />
      <w:lang w:eastAsia="en-GB" />
    </w:rPr>
    <w:t>]</w:t>
  </w:r>
</w:p>

上面显示了为 text 创建的打开 xml [text-to-replace]。(请注意,情况可能并非总是如此,可能取决于您使用的客户端)。

从您的代码的外观来看,您doc.MainDocumentPart.Document.Body.Descendants()正在OpenXmlPart为文档的整个正文采用所有类型的 Descendants 并尝试替换逐个迭代的文本,从而使实际文本位于一部分中,而特殊字符则位于两个部分中部分。因此,代码无法达到要求。

可能有不同的方法来解决这个问题。

解决方案:

一个不错的(我的首选)解决方案是使用来自OpenXml Powertools的 Markup Simplifier 规范化 xml ,这将规范化打开的 xml 标记以连接段落中的文本以简化编程工作。

示例代码:

using (WordprocessingDocument doc =
            WordprocessingDocument.Open("Test.docx", true))
 {
      SimplifyMarkupSettings settings = new SimplifyMarkupSettings
      {
             NormalizeXml = true, // Merges Run's in a paragraph with similar formatting

       };
        MarkupSimplifier.SimplifyMarkup(doc, settings);
  }

在此处参考我的回答以获取有关使用的更多信息MarkupSimplifier

希望这可以帮助 :)

于 2013-08-29T13:00:49.730 回答