问题
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
回答1:
This is modified version of code by @TLama from an answer to How to read and write XML document node values?
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 occured!' + #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>
来源:https://stackoverflow.com/questions/34889265/how-to-update-multiple-xml-nodes-in-a-loop-with-inno-setup