{"id":66843,"date":"2006-07-24T16:17:00","date_gmt":"2006-07-24T16:17:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2006\/07\/24\/how-can-i-replace-selected-lines-in-an-xml-file\/"},"modified":"2006-07-24T16:17:00","modified_gmt":"2006-07-24T16:17:00","slug":"how-can-i-replace-selected-lines-in-an-xml-file","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-replace-selected-lines-in-an-xml-file\/","title":{"rendered":"How Can I Replace Selected Lines in an XML File?"},"content":{"rendered":"<p><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Question\" border=\"0\" alt=\"Hey, Scripting Guy! Question\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" height=\"34\"> \n<P>Hey, Scripting Guy! How can I read lines 56 to 62 in one XML file, and replace those with lines 56 to 62 taken from another XML file?<BR><BR>&#8212; JA<\/P><IMG border=\"0\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" height=\"5\"><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Answer\" border=\"0\" alt=\"Hey, Scripting Guy! Answer\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" height=\"34\"><A href=\"http:\/\/go.microsoft.com\/fwlink\/?linkid=68779&amp;clcid=0x409\"><IMG class=\"farGraphic\" title=\"Script Center\" border=\"0\" alt=\"Script Center\" align=\"right\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/ad.jpg\" width=\"120\" height=\"288\"><\/A> \n<P>Hey, JA. First of all, we\u2019d like to thank you for your question; in addition, we\u2019d like to welcome you and everyone else to today\u2019s Open House in honor of the 501<SUP>st <\/SUP><I>Hey, Scripting Guy!<\/I> column. We know that \u2013 sorry, could we put you on hold for a second?<\/P>\n<P>Hmmm \u2026. The Scripting Editor has pointed out that we just had an <A href=\"http:\/\/null\/technet\/scriptcenter\/resources\/qanda\/postcards\/default.mspx\"><B>Open House<\/B><\/A> in honor of the 500<SUP>th<\/SUP> column and that there is no way we\u2019re having another one, not this soon anyway. To tell you the truth, that doesn\u2019t make much sense to us: if 500 columns are considered noteworthy, well, then wouldn\u2019t 501 columns be even better? But we aren\u2019t going to argue with her; we don\u2019t really want her turning us into newts.<\/P>\n<P>Like she did to poor Dean.<\/P>\n<P><I>(Editor\u2019s Note: The fact that Dean bears a striking resemblance to a newt has no connection to any special powers the Scripting Editor may or may not have.)<\/I><\/P>\n<P>So now what do we do? Seeing as how we aren\u2019t going to have another big party today, we might as well try to come up with a script that can replace selected lines in an XML file. A script like this one:<\/P><PRE class=\"codeSample\">Const ForReading = 1\nConst ForWriting = 2<\/p>\n<p>Set objFSo = CreateObject(&#8220;Scripting.FileSystemObject&#8221;)\nSet objFile = objFSO.OpenTextFile(&#8220;C:\\Scripts\\Test.xml&#8221;, ForReading)<\/p>\n<p>For i = 1 to 55\n    objFile.SkipLine\nNext<\/p>\n<p>For i = 1 to 7\n    strText = strText &amp; objFile.ReadLine &amp; vbCrLf\nNext<\/p>\n<p>objFile.Close<\/p>\n<p>Set objFile = objFSO.OpenTextFile(&#8220;C:\\Scripts\\New_test.xml&#8221;, ForReading)<\/p>\n<p>For i = 1 to 55\n    strNewText = strNewText &amp; objFile.ReadLine &amp; vbCrLf\nNext<\/p>\n<p>strNewText = strNewText &amp; strText<\/p>\n<p>For i = 1 to 7\n    objFile.SkipLine\nNext<\/p>\n<p>Do Until objFile.AtEndOfStream\n    strNewText = strNewText &amp; objFile.ReadLine &amp; vbCrLf\nLoop<\/p>\n<p>objFile.Close<\/p>\n<p>Set objFile = objFSO.OpenTextFile(&#8220;C:\\Scripts\\New_test.xml&#8221;, ForWriting)<\/p>\n<p>objFile.WriteLine strNewText<\/p>\n<p>objFile.Close\n<\/PRE>\n<P>The first thing you might have noticed about this script is that we don\u2019t use any fancy XML coding; instead we use the FileSystemObject and treat this XML file as if it was just another text file. Why do we do that? That\u2019s simple: an XML file <I>is<\/I> just another text file. Obviously there are times when you need to use the <A href=\"http:\/\/msdn.microsoft.com\/library\/en-us\/dnanchor\/html\/anch_xml.asp\" target=\"_blank\"><B>XML object model<\/B><\/A> to manipulate an XLM file; this isn\u2019t one of those times. <\/P>\n<P>So what <I>do<\/I> we do with this XML file? Well, we start off by defining a pair of constants: ForReading and ForWriting. We\u2019ll use these two constants to tell the FileSystemObject which mode (for reading or for writing) we want to use when opening the files. After defining the two constants we create an instance of the <B>Scripting.FileSystemObject<\/B> and then use the <B>OpenTextFile<\/B> method to open the file C:\\Scripts\\Test.xml, the file that contains the text we want to copy.<\/P>\n<P>Pretty easy so far, right? Of course, at this point it gets just a teeny-tiny bit tricky. We\u2019ve already decided that we don\u2019t want lines 1 through 55 of this file; we want only lines 56 through 62. Therefore, we set up a For Next loop that runs 55 times; inside that loop, we use the <B>SkipLine<\/B> method to simply skip past the line in the text file:<\/P><PRE class=\"codeSample\">For i = 1 to 55\n    objFile.SkipLine\nNext\n<\/PRE>\n<P>What does that do for us? That enables us to skip past the first 55 lines, leaving us exactly where we want to be: line 56. Having reached the promised land (or at least the promised line), we then set up another For Next loop, this one running from 1 to 7:<\/P><PRE class=\"codeSample\">For i = 1 to 7\n<\/PRE>\n<P>Why 1 to 7? That\u2019s easy: our goal now is to copy 7 lines out of the file: lines 56, 57, 58, 59, 60, 61, and 62. Thus a loop that runs from 1 to 7.<\/P>\n<P>Inside that loop we execute this line of code:<\/P><PRE class=\"codeSample\">strText = strText &amp; objFile.ReadLine &amp; vbCrLf\n<\/PRE>\n<P>What we\u2019re doing here is storing those 7 lines of text into a variable named strText. To do that we set the value of strText to the existing value of strText <I>plus<\/I> the current line in the text file (which we can retrieve using the <B>ReadLine<\/B> method), <I>plus<\/I> a carriage return-linefeed. For example, suppose lines 56 and 57 in the XML file consist of the following:<\/P><PRE class=\"codeSample\">&lt;computer&gt;\n    &lt;name&gt;\n<\/PRE>\n<P>The first time through the loop strText will be assigned the following:<\/P>\n<TABLE border=\"0\" cellSpacing=\"0\" cellPadding=\"0\">\n<TBODY>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>The current value of strText (which is nothing).<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>The value of line 56 (<B>&lt;computer&gt;<\/B>).<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>A carriage return-linefeed.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<P>The second time through the loop strText will be assigned the following:<\/P>\n<TABLE border=\"0\" cellSpacing=\"0\" cellPadding=\"0\">\n<TBODY>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>The current value of strText (<B>&lt;computer&gt;<\/B>, plus a carriage return-linefeed).<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>The value of line 57 ( <B>&lt;name&gt;<\/B>).<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>A carriage return-linefeed.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<P>Etc., etc.<\/P>\n<P>After we\u2019ve read lines 56-62 we\u2019re finished with Test.xml; therefore, we use this line of code to close the file and get on with our lives:<\/P><PRE class=\"codeSample\">objFile.Close\n<\/PRE>\n<P>So what exactly are we going to <I>do<\/I> with the rest of our lives? Well, the first thing we\u2019re going to do is open the file C:\\Scripts\\New_test.xml; this is the file where we want to insert the lines we just read in. Notice, however, that we don\u2019t open the file for writing; instead, we open it for reading:<\/P><PRE class=\"codeSample\">Set objFile = objFSO.OpenTextFile(&#8220;C:\\Scripts\\New_test.xml&#8221;, ForReading)\n<\/PRE>\n<P>What sort of madness is that? Well, unfortunately, we can\u2019t simply replace text in a text file; the FileSystemObject won\u2019t allow that. Therefore, what we need to do is construct a replacement file in memory: we need to read lines 1 through 55 in the current file, add the seven lines we copied from the first file, skip lines 56-62, and then add in the rest of New_test.xml. Confusing? You bet. But let\u2019s walk through it and see if we can explain how that all works.<\/P>\n<P>Reading lines 1 through 55 are easy: we just use this block of code, stashing the results in a variable named strNewText:<\/P><PRE class=\"codeSample\">For i = 1 to 55\n    strNewText = strNewText &amp; objFile.ReadLine &amp; vbCrLf\nNext\n<\/PRE>\n<P>Like we said, that was easy; we just did something very similar a few minutes ago. Once we have lines 1 through 55 safely stored away we can use this code to append the lines we copied from our first XML file:<\/P><PRE class=\"codeSample\">strNewText = strNewText &amp; strText\n<\/PRE>\n<P>That gives us \u2013 in memory \u2013 a 62-line text file: the first 55 lines having been read in from New_test.xml, the last 7 lines having been copied from Test.xml. What we need to do now is grab the rest of New_test.xml, beginning with line 63 and continuing to the end of the file. <\/P>\n<P>Why \u201cbeginning with line 63?\u201d Well, remember, lines 56 through 62 are already in place; that\u2019s what we copied from Test.xml. We need to skip lines 56 to 62 in New_test.xml, something we do using this block of code:<\/P><PRE class=\"codeSample\">For i = 1 to 7\n    objFile.SkipLine\nNext\n<\/PRE>\n<P>And then to get line 63 on through the end of the file we use this code:<\/P><PRE class=\"codeSample\">Do Until objFile.AtEndOfStream\n    strNewText = strNewText &amp; objFile.ReadLine &amp; vbCrLf\nLoop\n<\/PRE>\n<P>Make sense? If not, walk yourself through the script line-by-line. It might take a time or two, but it should become clear soon enough.<\/P>\n<P>Once we\u2019ve read through the rest of New_test.xml we close the file; that\u2019s because the file was originally opened for reading, which means we have to close the thing and then immediately reopen it <I>for writing<\/I>. (It sounds silly to us, too. But it is what it is.) We use these two lines of code to close and reopen the file:<\/P><PRE class=\"codeSample\">objFile.Close<\/p>\n<p>Set objFile = objFSO.OpenTextFile(&#8220;C:\\Scripts\\New_test.xml&#8221;, ForWriting)\n<\/PRE>\n<P>All we have to do now is write the contents of the variable strNewText to the file, close the file one last time, and then call it good.<\/P>\n<P>Granted, it seems a little convoluted, but it works. And, again, the same basic approach works on <I>any<\/I> text file, not just on XML files.<\/P>\n<P>We hope that helps, JA. And we hope that you \u2013 and everyone else \u2013 will come back tomorrow. As you probably know, tomorrow will be the 502<SUP>nd <\/SUP><I>Hey, Scripting Guy!<\/I> column, and we have a huge celebration planned.<\/P>\n<P>Well, as long as you-know-who doesn\u2019t find out, that is.<\/P>\n<P><I>(Editor\u2019s Note: Has anyone ever noticed that Greg has always kind of resembled a toad\u2026.)<\/I><\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! How can I read lines 56 to 62 in one XML file, and replace those with lines 56 to 62 taken from another XML file?&#8212; JA Hey, JA. First of all, we\u2019d like to thank you for your question; in addition, we\u2019d like to welcome you and everyone else to today\u2019s Open [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[3,4,14,5,165],"class_list":["post-66843","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-scripting-guy","tag-scripting-techniques","tag-text-files","tag-vbscript","tag-xml"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! How can I read lines 56 to 62 in one XML file, and replace those with lines 56 to 62 taken from another XML file?&#8212; JA Hey, JA. First of all, we\u2019d like to thank you for your question; in addition, we\u2019d like to welcome you and everyone else to today\u2019s Open [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/66843","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=66843"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/66843\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=66843"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=66843"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=66843"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}