1

I have to update a XML node that appears more than once, using Inno Setup.

How to do so?

For instance: I have to update <details> nodes (while I don't know how many nodes there are)

<server name="A">
    <details>id=5 gid=10</details>
</server>

<server name="B">
    <details>id=5 gid=10</details>
</server>

Thank you

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
Tamir Gefen
  • 1,128
  • 2
  • 18
  • 35

1 Answers1

4

This is modified version of code by @TLama from an answer to How to read and write XML document node values in Inno Setup?

In addition to his code, this version can update multiple nodes matching the XPath. The only difference is the call to selectNodes instead of selectSingleNode and the following for loop.

procedure SaveValueToXMLNodes(const AFileName, APath, AValue: string);
var
  XMLDocument: Variant;
  XMLNodeList: Variant;
  Index: Integer;
begin
  XMLDocument := CreateOleObject('Msxml2.DOMDocument.6.0');
  try
    XMLDocument.async := False;
    XMLDocument.load(AFileName);
    if XMLDocument.parseError.errorCode <> 0 then
    begin
      MsgBox(
        'The XML file could not be parsed. ' + XMLDocument.parseError.reason,
         mbError, MB_OK)
    end
      else
    begin
      XMLDocument.setProperty('SelectionLanguage', 'XPath');
      XMLNodeList := XMLDocument.selectNodes(APath);
      for Index := 0 to XMLNodeList.length - 1 do
      begin
        XMLNodeList.item[Index].text := AValue;
      end;
      XMLDocument.save(AFileName);
    end;
  except
    MsgBox('An error occurred!' + #13#10 + GetExceptionMessage, mbError, MB_OK);
  end;
end;

For an input file like:

<root>
    <server name="A">
        <details>id=5 gid=10</details>
    </server>
    <server name="B">
        <details>id=5 gid=10</details>
    </server>
</root>

you can use the code like:

SaveValueToXMLNodes('servers.xml', '/root/server/details', 'id=6 gid=11');

to get:

<root>
    <server name="A">
        <details>id=6 gid=11</details>
    </server>
    <server name="B">
        <details>id=6 gid=11</details>
    </server>
</root>
Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992