Создаем форму, на которой обязательно должны присутствовать кнопка открытия файла (и OpenDialog, соответственно) и TreeView. Остальное — опционально.
Подключаем библиотеки XmlDoc, XMLIntf (про XMLIntf, возможно, напишу отдельным постом).
Объявляем класс TNodeRec.
type
TNodeRec = class
TreeNode : TTreeNode;
XMLNode : iXMLNode;
end;
Переменные:
var
XDoc : TXMLDocument;
FName : String;
bkpXml : String;
CurrNode,
ClipboardNode : iXMLNode;
Функции:
function GetPathByNodeIdx (T : TTreeNode) : TStringList;
begin
Result:= TStringList.Create;
if T=nil then exit;
while T.Parent<>nil do
begin
Result.Insert(0,IntToStr(integer(T.Data)));
T:=T.Parent;
end;
Result.Insert(0,IntToStr(integer(T.Data)));
end;
function SetXmlPosByPathIdx (aSL: TStringList; aXmlDocument : TXMLDocument) : IXMLNode;
var
i : integer;
iNODE : IXMLNode;
begin
iNode:=nil;
if aSL.Count=0 then exit;
try
iNODE:=XDoc.ChildNodes.Nodes [StrToInt(aSL[0])];
for i:=1 to aSL.Count -1 do
iNode:=iNODE.ChildNodes[StrToInt(aSL[i])];
Result:=iNODE;
except
end;
end;
На OnCreate формы вешаем:
procedure TfrmMain.FormCreate(Sender: TObject);
begin
XDocNodesList:=TList.Create;
XDoc:=TXMLDocument.Create(Self);
XDoc.Active:=true;
OpenDialog.InitialDir:=ExtractFilePath(ParamStr(0));
end;
На OnDestroy:
procedure TfrmMain.FormDestroy(Sender: TObject);
begin
ClearNodeList;
XDocNodesList.Free;
XDoc.Free;
end;
Обработчик нажатия на кнопку "Загрузить XML":
procedure TfrmMain.acLoadExecute(Sender: TObject);
var
i : integer;
tmpNode : IXMLNode;
begin
if OpenDialog.Execute then
begin
FName:=OpenDialog.FileName;
SaveDialog.FileName:=FName;
XDoc.LoadFromFile(FName);
for i:=0 to XDoc.ChildNodes.Count - 1 do
begin
tmpNode:=XDoc.ChildNodes[i];
TreeView.Items.AddChildObject(TreeView.TopItem,tmpNode.NodeName,
pointer(i));
if tmpNode.HasChildNodes then TreeView.TopItem.HasChildren:=true;
end;
end;
acRefresh.Execute;
bkpXml:=XDoc.XML.Text;
end;
После этого мы уже можем в первый раз опробовать работу программы: в TreeView загрузится XML, но нам будет видно только рутовую вершину (как на 1-ом рисунке). Чтобы можно было разворачивать узлы и просматривать их текст и атрибуты — надо написать еще несколько обработчиков.
procedure TfrmMain.acRefreshExecute(Sender: TObject);
var
i : integer;
tmpNode : IXMLNode;
begin
RebuildTree;
acRefreshMemBody.execute;
end;
procedure TfrmMain.RebuildTree;
var
i : integer;
XNodeItem : iXmlNode;
PNodeItem,
SelectedTrNode,
TrNodeItem,
TrNodeChild : TTreeNode;
NodeRec,
ChildNodeRec : TNodeRec;
Index : integer;
SL : TStringList;
begin
SL:=GetPathByNodeIdx (TreeView.Selected);
CurrNode:=SetXmlPosByPathIdx (SL, XDoc);
SL.Free;
Index :=0;
TreeView.Items.Clear;
ClearNodeList;
NodeRec:=TNodeRec.Create;
TrNodeItem:=TreeView.TopItem;
NodeRec.TreeNode:=TrNodeItem;
XNodeItem:=XDoc.Node;
NodeRec.XMLNode:=XNodeItem;
XDocNodesList.Add(NodeRec);
while XDocNodesList.Count > Index do
begin
NodeRec:=TNodeRec(XDocNodesList[Index]);
XNodeItem:=NodeRec.XMLNode;
TrNodeItem:=NodeRec.TreeNode;
if XNodeItem=CurrNode then SelectedTrNode:=TrNodeItem;
for i:=0 to XNodeItem.ChildNodes.Count -1 do
begin
if XNodeItem.ChildNodes[i].NodeName<>'#text' then
TrNodeChild:=
TreeView.Items.AddChildObject(
TrNodeItem,
XNodeItem.ChildNodes[i].NodeName,
pointer(i));
ChildNodeRec:=TNodeRec.Create;
ChildNodeRec.TreeNode:=TrNodeChild;
ChildNodeRec.XMLNode:=XNodeItem.ChildNodes[i];
XDocNodesList.Add(ChildNodeRec);
end;
inc(Index);
end;
if SelectedTrNode<>nil then SelectedTrNode.Selected:=true;
TreeView.Select(SelectedTrNode,[]);
end;
Сейчас при перемещении по узлам уже наблюдаем более-менее приемлемый результат:
Дальше остается решить вопросы редактирования и добавления узлов и атрибутов.) Это будет домашним заданием.
___
Редакция от 13.01.2010
Продолжение цикла статей:
Добавление и удаление узлов (вершин) в XML в Delphi (с использованием компонента TTreeView). Там же вы найдете ссылку для скачивания исходников.
Прикольная статья ... а можна исходники ?
ОтветитьУдалитьНу тут и так все листинги приведены... Исходников у меня сейчас под рукой нет.
ОтветитьУдалитьЛистинги то приведены, но что то не получается сделать самому %)
ОтветитьУдалитьБуду очень благодарен если все же найдете исходники ...
Masha, очень нужна эта программа ... дайте плиз исходники, а то самому неполучается сделать %)
ОтветитьУдалитьMasha, как с вами связаться ?
ОтветитьУдалитьBOSS, связаться со мной можно по емейлу в профайле. Но если вы хотите связаться затем, чтобы получить исходники, - я вам ничем помочь не могу, их у меня на этой машине нет. Когда писала статью - делала программу, все работало, так что приведенные тут листинги - полностью рабочие и опробованные. А если у вас не получается по готовым листингам все восстановить - хм, тут уж я точно помочь не могу :) Заново делать форму и копировать все в проект у меня нет ни времени, ни желания, извините...)
ОтветитьУдалитьMasha выручайте в универе завал ... Дерево в тривью построил, а от отобразить атрибути и текст среди тегов не могу (так как у вас в последнем скриншоте).
ОтветитьУдалитьПомогите! буду очень благодарен !
Как же весело вызывать процедуры - acRefreshMemBody которых нет в статье!
ОтветитьУдалитьНда, кто нибудь пробывал по этим исходникам программу сделать? Да тут половины переменных нет!
ОтветитьУдалитьЭто дерево - не 'дуб' :)
ОтветитьУдалитьПеременных нет - создайте сами, функции обработки интерфейса сами допишете как вам нужно, может ей ещё листинг из System-а сюда?
Обращение к тем, кто решит оставить комментарий типа "нет половины кода", "ничего не пашет" и т.д. (регулярно отклоняю такие комментарии, так как прежде чем комментировать - надо как минимум внимательно прочитать). В конце статьи есть ссылка, по которой вы можете перейти на другую статью, в которой разжевано абсолютно все и кроме всего прочего приложены исходники. Пожалуйста, хотя бы уважайте чужой труд. И уж если у вас нет ума и терпения, чтобы по подсказкам добраться до верного решения, то обойдитесь без написания комментария.
ОтветитьУдалитьС уважением.
выдаёт ошибку
ОтветитьУдалить[dcc32 Error] Unit6.pas(93): E2003 Undeclared identifier: 'acRefresh'
и ещё такую
[dcc32 Error] Unit6.pas(108): E2003 Undeclared identifier: 'ClearNodeList'
Если эти строки закоментировать тогда потом выдаёт такую ошибку при выборе файла
Line: 1
<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD
Откуда вы берете все эти библиотеке сами что-ли пишите XmlDoc, XMLIntf потому, что пытался скачать в интернете о них и слова нет?
ОтветитьУдалить