unit Main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, xmldom, XMLIntf, msxmldom, XMLDoc, ComCtrls, StdCtrls, Buttons,
  ExtCtrls;

type
  TMainForm = class(TForm)
    Memo1: TMemo;
    Memo2: TMemo;
    OpenDialog: TOpenDialog;
    Panel1: TPanel;
    btnCLOSE: TBitBtn;
    btnLoad1: TBitBtn;
    btnLoad2: TBitBtn;
    btnLoad3: TBitBtn;
    TreeView: TTreeView;
    XMLDocument: TXMLDocument;
    Splitter1: TSplitter;
    Splitter2: TSplitter;
    procedure FormShow(Sender: TObject);
    procedure btnLoad3Click(Sender: TObject);
    procedure btnLoad2Click(Sender: TObject);
    procedure btnLoad1Click(Sender: TObject);
    procedure btnCLOSEClick(Sender: TObject);

  private

  public
	 AttrNode     : IXMLNode;	// tylko wskaźnik

	 procedure  Narysuj(wezel : IXMLNode);
	 procedure  DoTreeView(ixmlNode : IXMLNode; TreeNode : TTreeNode);
    procedure  Start();
  end;

var
  MainForm: TMainForm;

implementation
{$R *.dfm}
{------------------------------------------------------------------------------}
procedure TMainForm.btnCLOSEClick(Sender: TObject);
begin
	Close();
end;

procedure TMainForm.FormShow(Sender: TObject);
var
	szer : Integer;

begin
   Memo1.Clear();
   Memo2.Clear();
   TreeView.Items.Clear();

   szer := Screen.Width;
   szer := szer div 3;

   TreeView.Width := szer;
   Memo1.Width    := szer;
   Memo2.Width    := szer;
end;

procedure TMainForm.btnLoad1Click(Sender: TObject);
var
   fn : String;

begin
   Memo1.Clear();

	fn := '';
   fn :=  ExtractFilePath(Application.ExeName) + 'customers.xml';

   XMLDocument.FileName := fn;
   XMLDocument.Active := true;
   Memo1.Lines.Add(XMLDocument.XML.Text);
   XMLDocument.Active := false;
end;

procedure TMainForm.btnLoad2Click(Sender: TObject);
var
	fn      : String;
	element : IXMLNode;

begin
   Memo2.Clear();
   Memo2.Visible := false;

   fn :=  ExtractFilePath(Application.ExeName) + 'customers.xml';

   XMLDocument.FileName := fn;
   XMLDocument.Active := true;

   element := XMLDocument.DocumentElement;
   Narysuj(element);

   XMLDocument.Active := false;
   Memo2.Visible      := true;   
end;

procedure TMainForm.btnLoad3Click(Sender: TObject);
begin
	Start();
end;

procedure TMainForm.Start();
begin
   OpenDialog.InitialDir := ExtractFilePath(Application.ExeName);

   if OpenDialog.Execute() then
	begin
      TreeView.Items.Clear();

      XMLDocument.LoadFromFile(OpenDialog.FileName);

      DoTreeView(XMLDocument.DocumentElement, Nil);

      TreeView.FullExpand();
   end;
end;

procedure TMainForm.Narysuj(wezel: IXMLNode);
var
	nazwa_wezla : String;
   lp          : Integer;

begin
	if wezel.NodeType <> ntElement then
	begin
		exit;
   end;

	nazwa_wezla := wezel.NodeName;
   if wezel.IsTextElement then
	begin
      nazwa_wezla := nazwa_wezla + ' = ' + wezel.NodeValue;
   end;

   // odczytanie wszystkich atrybutów danego elementu
   // nazwa atrybutu dostępna przez atrybut->NodeName
   // wartośc atrybutu dostepna przez atrybut->Text
   // przechodzimy przez jego węzły dzieci
   if wezel.HasChildNodes then
   begin
		for lp := 0 to wezel.ChildNodes.Count-1 do
      begin
      	Narysuj(wezel.ChildNodes.Nodes[lp]);
      end;
   end;

   Memo2.Lines.Add(nazwa_wezla);
end;

procedure TMainForm.DoTreeView(ixmlNode: IXMLNode; TreeNode: TTreeNode);
var
	NewTreeNode  : TTreeNode;
   lp           : Integer;
   NodeText     : String;
   txt          : String;

begin
   // przeskocz węzly tekstu i inne specjalne przypadki
	if ixmlNode.NodeType <> ntElement then
   begin
   	exit;
   end;

   // dodaj sam węzel
   NodeText := ixmlNode.NodeName;
   if ixmlNode.IsTextElement then
	begin
   	NodeText := NodeText + ' = ' + ixmlNode.NodeValue;
   end;

   // NewTreeNode tylko wskazuje
   NewTreeNode := TreeView.Items.AddChild(TreeNode, NodeText);

   // dodaj atrybuty
   for lp := 0 to ixmlNode.AttributeNodes.Count-1 do
	begin
      AttrNode := ixmlNode.AttributeNodes.Nodes[lp];
		txt      := Trim(AttrNode.Text);
		txt      := ' ' + txt;
		TreeView.Items.AddChild(NewTreeNode, AttrNode.NodeName + txt);
   end;

	// dodaj każdy wezel podrzedny
	if ixmlNode.HasChildNodes then
	begin
		for lp := 0 to ixmlNode.ChildNodes.Count-1 do
   	begin
			DoTreeView(ixmlNode.ChildNodes.Nodes[lp], NewTreeNode);
      end;
   end;
end;

end.

