我可以在 Delphi 中将 msxml.IXMLDOMNode 转换为 XmlIntf.IXMLNode 吗?

发布于 2024-12-16 01:19:45 字数 456 浏览 0 评论 0原文

我已将 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;

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;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

黒涩兲箜 2024-12-23 01:19:45

您可以创建一个 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.

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.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文