Могу ли я преобразовать msxml.IXMLDOMNode - XmlIntf.IXMLNode в Delphi?
Я прочитал som xml в msxml.Объект IXMLDOMDocument. Однако в API, который я использую, есть метод утилиты, который я хотел бы вызвать, но он принимает XmlIntf.IXMLNode в качестве аргумента.
есть ли простой способ преобразовать экземпляр IXMLDOMNode из моего документа в IXMLNode, чтобы я мог передать его методу без необходимости загружать xml в объект TXmlDocument?
на данный момент я реализовал этот обходной путь:
function ConvertNode(const Node: IXMLDOMNode): IXMLNode;
var
Document: IXMLDocument;
begin
Document := NewXMLDocument;
Document.LoadFromXML(Node.xml);
Result := Document.DocumentElement;
end;
1 ответов
вы можете создать экземпляр IXMLDocument
и "прикрепите" его к вашему IXMLDOMDocument
. Вот небольшой пример:
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.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.