В прошлый раз мы строили дерево TreeView по данным из XML-документа. Сегодня проведем обратное преобразование — сохраним дерево TreeView любой сложности в XML-файл, чтобы довести работу до логического завершения. Раз научились читать документ — надо научиться его и правильно сохранять.
Для решеня этой задачи вы можете воспользоваться как прошлым примером и уже имеющимся списком узлов TNodeList, так и процедурой, которую мы рассмотрим в этом посте.
Для решения задачи нам потребуется опять же:
1. Модули XMLDoc и XMLIntf для работы с XML
2. Компонент TreeView
Для сохранения дерева TreeView в XML будем использовать рекурсию. Работу организуем следующим образом:
1. Создадим объект TXMLDocument или воспользуемся IXMLDocument — не важно.
2. Создадим один узел (Root Node) с необходимыми нам атриутами
3. Создадим процедуру-обработчик для каждого элемента TreeView
4. Используя процедуру-обработчик, рекурсивно обойдем все узлы дерева и запишем данные из них в XML-документ
5. Сохраним XML-документ в файл.
Начнем с процедуры-обработчика. В принципе, она не сильно будет отличаться от аналогичной уже рассмотренной. Выглядит она следующим образом:
procedure ProcessTreeItem(tn: TTreeNode; iNode: IXMLNode); var cNode : IXMLNode; begin if (tn = nil) then Exit; cNode:= iNode.AddChild(tn.Text);//имя узла {атрибуы узла} cNode.Attributes['Text'] := tn.Text; cNode.Attributes['Level'] := IntToStr(tn.Level); //дочерние узлы tn := tn.getFirstChild; while tn <> nil do begin ProcessTreeItem(tn, cNode); tn := tn.getNextSibling; end; end;
То есть в ProcessTreeItem мы динамически создаем узлы XML-документа, присваивая им необходимые имена и атрибуты и работая на том же уровне, что и iNode (вызывающий узел). Можете доработать обработчик в соответствии со своими потребностями. Например, можно сделать, чтобы имена присваивались не по названию узла в дереве, а теже, что и спользовались в списке TNodeList и т.д..
Теперь напишем саму процедуру сохранения дерева, включив в неё и приведенную выше ProcessTreeItem. Вот полный листинг процедуры сохранения TreeView в XML-файл:
procedure TXMLTree.SaveTreeToXML; var tn : TTreeNode; XMLDoc : TXMLDocument; iNode : IXMLNode; procedure ProcessTreeItem(tn: TTreeNode; iNode: IXMLNode); var cNode : IXMLNode; begin if (tn = nil) then Exit; cNode:= iNode.AddChild(tn.Text);//имя узла {атрибуы узла} cNode.Attributes['Text'] := tn.Text; cNode.Attributes['Level'] := IntToStr(tn.Level); //дочерние узлы tn := tn.getFirstChild; while tn <> nil do begin ProcessTreeItem(tn, cNode); tn := tn.getNextSibling; end; end; begin XMLDoc := TXMLDocument.Create(nil); XMLDoc.Active := True; iNode := XMLDoc.AddChild('Skin');//создаем корневой элемент //атрибуты корневого узла iNode.Attributes['name']:='MySkin'; iNode.Attributes['author']:='vlad'; tn := Tree.TopItem; while tn <> nil do //бегаем в цикле пока не пройдемся по всем узлам TreeView begin ProcessTreeItem (tn, iNode); tn := tn.getNextSibling; end; //сохраняем файл XMLDoc.SaveToFile(ChangeFileExt(ParamStr(0),'.XML')); //уничтожаем объект XMLDoc := nil end;
Вот собственно и вся работа по сохранению TreeView в XML. Все достаточно просто и компактно.
while tn <> nil do //бегаем в цикле пока не пройдемся по всем узлам TreeView
[Error] Unit1.pas(170): Illegal character in input file: ‘&’ ($26)