我已将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;
答案 0 :(得分:11)
您可以创建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\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.