I have read som xml into an msxml.IXMLDOMDocument object. However, there is a utility method in an API that I am using, that I would like to call, but it takes an XmlIntf.IXMLNode as an argument.
Is there a simple way to convert an IXMLDOMNode instance from my document to an IXMLNode so I can pass it to the method without having to load the xml into a TXmlDocument object?
For now I have implemented this workaround:
function ConvertNode(const Node: IXMLDOMNode): IXMLNode;
var
Document: IXMLDocument;
begin
Document := NewXMLDocument;
Document.LoadFromXML(Node.xml);
Result := Document.DocumentElement;
end;
You can create an instance of IXMLDocument
and "attach" it to your IXMLDOMDocument
. Here's a small example:
program msxmltest;
{$APPTYPE CONSOLE}
uses
SysUtils, ActiveX,
msxml, msxmldom,
xmldom,
XMLIntf, XMLDoc;
function MSDOMDocumentToDOMDocument(const MSDOMDocument: IXMLDOMDocument): IDOMDocument;
begin
Result := TMSDOMDocument.Create(MSDOMDocument) as IDOMDocument;
end;
function MSDOMNodeToDOMNode(const MSDOMNode: IXMLDOMNode): IDOMNode;
const
NodeClasses: array[ELEMENT_NODE..NOTATION_NODE] of TMSDOMNodeClass =
(TMSDOMElement, TMSDOMAttr, TMSDOMText, TMSDOMCDataSection,
TMSDOMEntityReference, TMSDOMEntity, TMSDOMProcessingInstruction,
TMSDOMComment, TMSDOMDocument, TMSDOMDocumentType, TMSDOMDocumentFragment,
TMSDOMNotation);
begin
Result := NodeClasses[MSDOMNode.nodeType].Create(MSDOMNode) as IDOMNode;
end;
function MSDOMNodeToXMLNode(const MSDOMNode: IXMLDOMNode; var OwnerDocument: IXMLDocument): IXMLNode;
begin
Result := nil;
if not Assigned(MSDOMNode) then
Exit;
if not Assigned(OwnerDocument) then
begin
OwnerDocument := TXMLDocument.Create(nil);
OwnerDocument.DOMDocument := MSDOMDocumentToDOMDocument(MSDOMNode.ownerDocument);
end;
Result := TXMLNode.Create(MSDOMNodeToDOMNode(MSDOMNode), nil, (OwnerDocument as IXMLDocumentAccess).DocumentObject);
end;
var
Indent: Integer = 0;
procedure ShowNode(const Node: IXMLNode);
var
I: Integer;
begin
Inc(Indent);
Writeln;
Writeln(StringOfChar(' ', Indent * 2) + 'NodeName: ' + Node.NodeName);
Writeln(StringOfChar(' ', Indent * 2) + 'NodeType: ' + NodeTypeNames[Node.NodeType]);
for I := 0 to Node.AttributeNodes.Count - 1 do
ShowNode(Node.AttributeNodes[I]);
if Node.HasChildNodes then
for I := 0 to Node.ChildNodes.Count - 1 do
ShowNode(Node.ChildNodes[I])
else
Writeln(StringOfChar(' ', Indent * 2) + 'NodeValue: ' + Node.NodeValue);
Dec(Indent);
end;
procedure Main;
var
MSDOMDocument: IXMLDOMDocument;
XMLDocument: IXMLDocument;
MSDOMNode: IXMLDOMNode;
begin
MSDOMDocument := CoDOMDocument.Create;
MSDOMDocument.load('C:\Program Files\Embarcadero\RAD Studio\8.0\ObjRepos\en\Code_Templates\Delphi\blockcomment.xml');
MSDOMNode := MSDOMDocument.documentElement;
// show all
ShowNode(MSDOMNodeToXMLNode(MSDOMNode, XMLDocument)); // you can reuse XMLDocument
Writeln;
// show author
MSDOMNode := MSDOMDocument.selectSingleNode('/codetemplate/template/author');
ShowNode(MSDOMNodeToXMLNode(MSDOMNode, XMLDocument));
Readln;
end;
begin
ReportMemoryLeaksOnShutdown := True;
try
CoInitialize(nil);
try
Main;
finally
CoUninitialize;
end;
except
on E: Exception do
begin
ExitCode := 1;
Writeln(Format('[%s] %s', [E.ClassName, E.Message]));
end;
end;
end.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With