How do I correctly use the Variant type (Here: msxml MSXML2.DOMDocument.6.0)?
Consider those two functions. The second one fails with an access violation exception if called twice:
function CreateElementWorking(xmlDocument: Variant; name : String) : Variant;
var
xmlNewElement : Variant;
begin
Result := xmlDocument.createElement(name);
xmlNewElement := Result;
// Do sth. with the newly created element
AddAttributes(xmlDocument, xmlNewElement);
end;
function CreateElementFailing(xmlDocument: Variant; name : String) : Variant;
var
xmlNewElement : Variant;
begin
xmlNewElement := xmlDocument.createElement(name);
// Do sth. with the newly created element
AddAttributes(xmlDocument, xmlNewElement);
// When the function runs for the 2nd time, "Result" is no longer uninitialized.
// Pascal scripting preserves the old value.
// The assignment results in an access violation exception
Result := xmlNewElement;
end;
Possible reason for the fail on second run is that Result already has a value. Pascal scripting somehow preserves the value from the first run.
The workaround in the first function does what I expect it does, although I don't know why it works. That always leaves a strange feeling...
Is there a way to reset Result prior to call Result := xmlNewElement; or is my Variant handling completely wrong?
Failing minimal example:
function AddAttributes(xmlDocument, xmlElement: Variant) : Variant;
begin
end;
function DoTest() : Boolean;
var
xmlDocument : Variant;
xmlElement : Variant;
xmlRootElement : Variant;
begin
xmlDocument := CreateOleObject('MSXML2.DOMDocument.6.0');
xmlDocument.async := False;
xmlDocument.setProperty('SelectionLanguage', 'XPath');
xmlRootElement := xmlDocument.selectSingleNode('/');
xmlElement := CreateElementFailing(xmlDocument, 'Test');
xmlRootElement.appendChild(xmlElement);
xmlRootElement := xmlDocument.selectSingleNode('/Test');
xmlElement := CreateElementFailing(xmlDocument, 'Test'); // This fails
xmlRootElement.appendChild(xmlElement);
// Result should be
// <Test><Test/></Test>
end;