title: How to update attributes in an XML file with InstallScript
body: <p><strong>Question:</strong></p>
  
  <p>I am struggling trying to figure out how to update some attributes in an XML file using InstallScript. I would like to use proper XML parsing functions, but I can't find anything that suggests this version of InstallScript is capable of it. How can I do this? Should I just attempt falling back on a combination of FileInsertLine and FileGrep? Is there a library I'm missing?</p>
  
  <p><strong>Background:</strong></p>
  
  <p><strong>What software versions?</strong><br>
  I am using InstallShield 11 on Windows Server 2003 R2.</p>
  
  <p><strong>Why am I not just using the existing 'XML File Changes' feature?</strong><br>
  Because I am doing an upgrade and running into <a href="http://installjournal.blogspot.com/2009/11/issue-in-minor-upgrade-files-not-copied.html" rel="nofollow">this bug</a>. It affects the XML File Change feature because it is tied to a Component (well, that's my guess). I spent too long trying the official workaround, but couldn't coax it to work. I eventually found out it was much easier and more reliable to copy the files over using InstallScript + a single line batch file. It feels a bit hacky, but it is something that actually works.</p>
  
  <p>Now I am trying to figure out the easiest and simplest-to-figure-out-years-later way to replicate the effects of the 'XML File Changes' feature in InstallScript.</p>
  
  <p>Please let me know if you need <strong>any</strong> more information, I will be glad to provide it.</p>
  
  <p><strong>EDIT:</strong>  </p>
  
  <p>I ended up going with the InstallScript way to do it after all - it has tended to be the way that everything else in this installer project was implemented, and it looked (and turned out to be) pretty quick to do. I started out with the code <a href="http://community.flexerasoftware.com/showpost.php?p=415221&amp;postcount=8" rel="nofollow">shown by TheTraveler</a> in that thread and modified it to suit my needs. </p>
  
  <p>Here is the code:  </p>
  
  <pre><code>prototype UpdateWebConfigAttributes();  
  prototype ReplaceValueOf(OBJECT, STRING, STRING);   
  
  function UpdateWebConfigAttributes()
      OBJECT oDoc, oNode;
      NUMBER i;                  
      STRING sWebConfigFilePath;   
      BOOL successfulLoad;
  begin   
  
      sWebConfigFilePath = "Path\\To\\Web.config";  
  
      if Is(FILE_EXISTS, sWebConfigFilePath) = FALSE then
          MessageBox("Could not find Web.config file.", 0);
      endif;
  
      // get values from public properties
      set oDoc = CreateObject("Msxml2.DOMDocument.4.0");  
      if !IsObject(oDoc) then
          MessageBox("Could not create XML Document", 0);
          return -1;     
      endif;     
  
      oDoc.async = FALSE;  
      oDoc.setProperty("SelectionLanguage", "XPath");
  
      successfulLoad = oDoc.load(sWebConfigFilePath);
      if !successfulLoad then
          MessageBox("Could not load Web.config as an xml file", SEVERE);                         
          return -1;
      endif;
  
      ReplaceValueOf(oDoc, "//add[@key=\"ConnectionDriver\"]", CONNECT_DRIVER);
      ReplaceValueOf(oDoc, "//add[@key=\"ConnectionType\"]", CONNECT_TYPE);
      ReplaceValueOf(oDoc, "//add[@key=\"ConnectionString\"]", CONNECT_STRING_WEBCONFIG);
      ReplaceValueOf(oDoc, "//add[@key=\"ShowConnection\"]", "False");
  
      oDoc.save(sWebConfigFilePath);
      set oDoc = NOTHING;
  end;   
  
  
  function ReplaceValueOf(oDoc, xPath, valueToPutIn)
      OBJECT oNode;
  begin
      set oNode = oDoc.selectNodes(xPath)(0);
      try
          oNode.attributes.getNamedItem("value").value = valueToPutIn;
      catch 
          MessageBox("Could not set '" + xPath + "' with '" + valueToPutIn + "'", SEVERE);
      endcatch;  
  end;    
  </code></pre>