Once I needed to work with Delphi 5 XML I gave a C # dll and created a unit in Delphi to serve as the interface.
I'll give you a paste of the code, it's kind of great, and it has many functions to call the metadata that was created in my .Net class
I basically load the dll and keep it in memory in a static class.
You can ignore 90% of the code that is to manipulate an array (of arrays) of strings and "simulate" a pseudo xml.
Take a look at the part where you have ProgID of the dll!
//****************************************************************************//
//*** Unit para servir de interface para ***//
//*** a DLL útil implementada em .Net ***//
//*** ***//
//*** 28/04/2010 ***//
//*** by Jean Charles Bulinckx ***//
//****************************************************************************//
unit uUtil;
interface
uses
ComObj, ComCtrls;
type
// XML serializado retornado pela DLL
tArrayNos = Array of Array of String;
// estrutura que representa o XML DEsSerializado pelo Delphi
tNo = class
nome:String;
valor:String;
id:String;
idPai:String;
filhos:Array of tNo;
end;
tArrNo = Array of tNo;
tUtil = class
private
// Mantém a DLL em memória
DLL: Variant;
public
// Metódos que chamam a dll
function Importar(servico, arquivo, login, senha: String):String;
function LeXML(arquivo:String):tArrayNos;
function Criptografar(dados:String; descriptar:Boolean):String;
// Métodos para ler/montar árvore
function EncontrarFilho(nome: String; raiz: tNo):tNo;
function EncontrarFilhos(nome: String; raiz: tNo):tArrNo;
function EncontrarRaiz(id: String; xml: tArrayNos):tNo;
function MontarFilhos(raiz:tNo; xml: tArrayNos):tNo;
function DeSerializarArvore(xml: tArrayNos):tNo;
function ReSerializarArvore(no: tNo):tArrayNos;
published
Constructor Inicializar();
end;
// ProgId da DLL
Const
NomeClasse:String = 'Xpto.Util';
implementation
function InstanciaClasse(strClasse: String):Variant;
begin
result := CreateOleObject(strClasse);
end;
// Função que retorna uma instância da classe
Constructor tUtil.Inicializar();
begin
inherited;
self.DLL := InstanciaClasse(NomeClasse);
end;
// ********************************
// *** Funções que chamam a DLL ***
// ********************************
function tUtil.Importar(servico, arquivo, login, senha: String):String;
begin
result := self.DLL.ChamarWSB(servico,arquivo, login, senha, false);
end;
function tUtil.LeXML(arquivo:String):tArrayNos;
begin
result := self.DLL.LerXML(arquivo);
end;
function tUtil.Criptografar(dados:String; descriptar:Boolean):String;
begin
result := self.DLL.Criptografar(dados, descriptar);
end;
// ********************************
// *** Funções que chamam a DLL ***
// ********************************
// *****************************************************
// *** Funções para "ler" a árvore de nós (tags) xml ***
// *****************************************************
// Encontra o filho pelo nome
function tUtil.EncontrarFilho(nome: String; raiz: tNo):tNo;
var no:tNo;
i:integer;
begin
no := tNo.Create();
for i := 0 to Length(raiz.filhos) - 1
do begin
if (raiz.filhos[i].nome = nome)
then begin
no := raiz.filhos[i];
end;
end;
result := no;
end;
// Encontrar uma coleção de filhos pelo nome
function tUtil.EncontrarFilhos(nome: String; raiz: tNo):tArrNo;
var arrNo:tArrNo;
i,l:integer;
begin
for i := 0 to Length(raiz.filhos) - 1
do begin
if (raiz.filhos[i].nome = nome)
then begin
l := Length(arrNo);
SetLength(arrNo,l+1);
arrNo[l] := raiz.filhos[i];
end;
end;
result := arrNo;
end;
// Acha quem é a raiz (quem não tem pai)
function tUtil.EncontrarRaiz(id: String; xml: tArrayNos):tNo;
var no:tNo;
i:integer;
id2:String;
begin
no := tNo.Create();
for i := 0 to Length(xml) - 1
do begin
id2 := xml[i,3];// id do pai
if (id=id2)
then begin
no.nome := xml[i,0];
no.valor := xml[i,1];
no.id := xml[i,2];
no.idPai := xml[i,3];
end;
end;
result := no;
end;
// Monta um ramo de árvore recursivamente
function tUtil.MontarFilhos(raiz:tNo; xml: tArrayNos):tNo;
var
no:tNo;
i,l:integer;
idPai:String;
begin
for i := 0 to Length(xml) - 1
do begin
idPai := xml[i,3];//id do pai
if (idPai = raiz.id)
then begin
no := tNo.Create();
no.nome := xml[i,0];
no.valor := xml[i,1];
no.id := xml[i,2];
no.idPai := xml[i,3];
no := MontarFilhos(no,xml);
l:=Length(raiz.filhos);
SetLength(raiz.filhos,l+1);
raiz.filhos[l]:=no;
end;
end;
result := raiz;
end;
// Remonta numa estrutura em memória o .XML serializado pela DLL
function tUtil.DeSerializarArvore(xml: tArrayNos):tNo;
var raiz:tNo;
begin
raiz := EncontrarRaiz('00000000-0000-0000-0000-000000000000', xml);
// Monta os filhos recursivamente
raiz := MontarFilhos(raiz, xml);
// Retorna a árvore em memória
result := raiz;
end;
// ReSerializa uma árvore para um Array of Arrays of String
function tUtil.ReSerializarArvore(no: tNo):tArrayNos;
var xml,ramo:tArrayNos;
i,j,lenPai,lenFilho,lenNeto:integer;
begin
ramo := nil;
if no <> nil
then begin
SetLength(xml,1,4);
xml[0,0] := no.nome;
xml[0,1] := no.valor;
xml[0,2] := no.id;
xml[0,3] := no.idPai;
// recursão
lenFilho := Length(no.Filhos);
for i := 0 to lenFilho - 1
do begin
ramo := ReSerializarArvore(no.Filhos[i]);
lenNeto := Length(ramo);
lenPai := Length(xml);
SetLength(xml,lenPai+lenNeto,4);
for j := 0 to lenNeto - 1
do begin
xml[lenPai + j] := ramo[j];
end
end
end;
result := xml;
end;
// *****************************************************
// *** Funções para "ler" a árvore de nós (tags) xml ***
// *****************************************************
end.