{"id":2687,"date":"2016-03-18T11:50:58","date_gmt":"2016-03-18T11:50:58","guid":{"rendered":"http:\/\/www.ericwhite.com\/home2\/bm8qcmjy\/public_html\/blog\/?page_id=2687"},"modified":"2016-03-20T10:00:22","modified_gmt":"2016-03-20T10:00:22","slug":"introducing-textreplacer-a-new-class-for-powertools-for-open-xml","status":"publish","type":"page","link":"https:\/\/www.ericwhite.com\/blog\/introducing-textreplacer-a-new-class-for-powertools-for-open-xml\/","title":{"rendered":"Introducing TextReplacer: A New Class for PowerTools for Open XML"},"content":{"rendered":"<p>Recently I wrote some code that implemented <a href=\"https:\/\/www.ericwhite.com\/blog\/search-and-replace-text-in-an-open-xml-wordprocessingml-document\/\">search-and-replacefor Open XML WordprocessingML documents<\/a>.&nbsp;I wrote that code for an Open XML developer who needed to implement thatfunctionality using XML DOM, although with a different language than C#.&nbsp; Because XML DOM is standardized,translating the code to another language and another implementation of XML DOMis relatively straightforward.<\/p>\n<p>I want to introduce search-and-replace functionality in a CMDLET in <a href=\"https:\/\/github.com\/OfficeDev\/Open-Xml-PowerTools\">PowerTools for Open XML<\/a>, but I have been moving PowerTools code away from XmlDocument, so I rewrote the search-and-replace code using LINQ to XML, using a functional transform.&nbsp; It was an interesting and fun project.&nbsp; The video below introduces the TextReplacer class, and compares it to the code that I presented that uses XmlDocument.&nbsp; It is an interesting comparison of imperative code (using XmlDocument) and functional code (using LINQ to XML).<\/p>\n<p>It took me about 8 hours to write the search-and-replace code using XmlDocument.&nbsp; It took me about 4 hourz to write the same code using LINQ to XML.&nbsp; However, for what it\u2019s worth, I spent far longer than that on both versions of the code making sure that whatever else happens, the code will not corrupt WordprocessingML documents.<\/p>\n<p>Personally, I find the functional code to be much cleaner and easier to maintain.&nbsp; It was also easier to debug.<\/p>\n<p>If you want to see a detailed description of the algorithm that I used for search-and-replace, see the <a href=\"https:\/\/www.ericwhite.com\/blog\/search-and-replace-text-in-an-open-xml-wordprocessingml-document\/\">previous post on search-and-replace<\/a> that uses XmlDocument.&nbsp; The approach that I took with the LINQ to XML code is identical in nature to the code that uses XmlDocument.&nbsp; This will be apparent in the video.<\/p>\n<p>I am currently in process of doing some relatively major revamps to PowerTools for Open XML, so I haven\u2019t posted this code on CodePlex yet.&nbsp; You can retrieve the code as an attachment to this post.<\/p>\n<p><iframe loading=\"lazy\" title=\"TextReplacer.wmv\" width=\"500\" height=\"281\" src=\"https:\/\/www.youtube.com\/embed\/G4s_BbGJ17E?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/p>\n<p>Download &#8211; <a href=\"https:\/\/www.ericwhite.com\/blog\/wp-content\/uploads\/2016\/03\/TextReplacer.zip\">Example Code<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Recently I wrote some code that implemented search-and-replacefor Open XML WordprocessingML documents.&nbsp;I wrote that code for an Open XML developer who needed to implement thatfunctionality using XML DOM, although with a different language than C#.&nbsp; Because XML DOM is standardized,translating the code to another language and another implementation of XML DOMis relatively straightforward. I want [&hellip;]<\/p>\n","protected":false},"author":10567,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"_s2mail":"","footnotes":""},"class_list":["post-2687","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.ericwhite.com\/blog\/wp-json\/wp\/v2\/pages\/2687","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.ericwhite.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.ericwhite.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.ericwhite.com\/blog\/wp-json\/wp\/v2\/users\/10567"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ericwhite.com\/blog\/wp-json\/wp\/v2\/comments?post=2687"}],"version-history":[{"count":5,"href":"https:\/\/www.ericwhite.com\/blog\/wp-json\/wp\/v2\/pages\/2687\/revisions"}],"predecessor-version":[{"id":2705,"href":"https:\/\/www.ericwhite.com\/blog\/wp-json\/wp\/v2\/pages\/2687\/revisions\/2705"}],"wp:attachment":[{"href":"https:\/\/www.ericwhite.com\/blog\/wp-json\/wp\/v2\/media?parent=2687"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}