2013-08-26 83 views
1

看看这篇文章的结尾,用文本框添加这个问题!如何用特殊字符替换XML文档中的文本?

用这种方法我想打开一个文档,替换一些文本,然后让它独自一人。它的作品,这是值得骄傲的东西。 :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(); 
      } 
     } 

但它只能在更换无特殊字符。 例如:

OS将与视窗9000

[OS]会留下,因为它是被替换。

CASE 1:

在文档:

You use os for whatever purpose you've got.

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

会导致这样的:

You use Win 2000 for whatever purpose you've got.

CASE 2:

有特殊字符...

You use [os] for whatever purpose you've got.

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

...它只是不理我:

You use [os] for whatever purpose you've got.

我试了几个特殊字符()[] {}等,但他们永远不会被取代。

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

有没有人帮助我的绝望? :)

SOLUTION /加入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(); 
      } 
     } 

(此代码将工作与在其正常的文字正常文档!)

SOLUTION /添加2: 如果你想要取代文本框中的文字,我不得不做一些小的解决方法。 文本框被声明为图片,所以上面的代码不会触及它。

我发现了一个额外的类(link),它甚至可以通过文本框搜索。 ZIP下载包括一个exmaple程序,易于理解。

+2

你的榜样输入/输出是不太清楚。请更具体地说明其当前正确/不正确的行为以及您希望不正确的行为。 – tnw

+0

对问题没有清楚的认识! – Irfan

+0

对不起!让我只是编辑这个给你... – Trollwut

回答

2

发生这种情况,因为当文本包含特殊字符看起来像打开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-to-replace]创建上面显示的Open XML。 (请注意,情况并非总是如此,可能取决于您使用的客户端)。

通过您的代码的外观doc.MainDocumentPart.Document.Body.Descendants()您正在采取所有OpenXmlPart类型后裔为整个文档的身体,并试图取代逐一迭代的文本,使实际文本在一个部分和两个特殊部分中的特殊字符。因此,代码不能满足要求。

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

解决方案:

一个很好(我的优选的)解决方案将是正常化使用标记简化器从OpenXml Powertools的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); 
    } 

请参阅我的回答here更多信息使用MarkupSimplifier

希望这有助于:)

+0

啊,是的,我可以跟着你。我遵循README文件中的安装说明,但无法完成它。我得到了缺失的'System.Management.Automation'工作,但我现在陷入了另一个错误:类型或命名空间“OutputTypeAttribute”无法找到(德语翻译)。你有解决方案吗?此外,我现在正在搜索这个问题。 :) – Trollwut

+0

是否有可能我已经(虽然PowerShell的新安装)该DLL的旧版本?如果是这样:如何更新它? – Trollwut

+0

我试图用PowerShell中的几个命令(例如'Copy([PSObject] .Assembly.Location)C:\')复制这个DLL,但是我解决不了我的问题。互联网上的人们说,他们可能会得到一个大小约3 MB的版本,但我的总是2.6 MB。 (只是写这个通知你我的尝试。) – Trollwut