Подписка

добавить на Яндекс

Наши проекты

Delphi+Google

Google API

Google API в Delphi - проект с открытым исходным кодом.

Chrono

Chrono

Хронометр - программа для ведения списка задач.

ODFProc

ODFProc

ODFProc - работа с документами OpenOffice в Lazarus и FreePascal.

Поддержка блога

А тут я коплю на лицензию Delphi XE на iPad =).
Сумма пожертвования не фиксирована.

Публикации

Год назад

Случайный пост

Последние

Сообщения форума

Комментарии

Социальные сети

Google

Facebook

Twitter

Опрос

Вы сейчас или в ближайшем обозримом будущем планируете разрабатывать кроссплатформенное приложение с использованием Firemonkey?



Loading ... Loading ...

Блоги и сообщества

Статьи по Delphi DelphiFeeds.ru - Все Delphi-блоги Рунета Сообщество умных людей VR-Online.RU Бесплатный журнал для программистов и всех, кто интересуется IT Статьи и уроки по Delphi Новостной блог о высоких технологиях
Система Orphus
Опубликовал Vlad 16 февраля 2010 в 17:28.
Категории: Delphi в Web.


Так как в последнее время очень много работаю с XML-документами различно сложности, то в процессе работы родилась небольшая идея - написать микро-приложение с помощью которого можно проследить логику документа в принципе, т.е. посмотреть уровень вложенности узлов, в случае необходимости - отметить определенные узлы как-либо и т.д. Пока количество узлов и их аттрибутов не велико, то с задачей вполне справиться любой браузер, но, когда у каждого узла по куче атрибутов, а сам документ имеет большую вложенность узлов, то как-то становиться жалко ломать глаза.Вот и родилась идея этого приложения, как вспомогательного инструмента для разбора XML и предоставления его в виде TreeView.

< ' ' >Работать будем сегодня вот с чем:

  • модули xmldoc, XMLIntf;
  • XML-файл по-сложнее и по-больше
  • ну и конечно же TreeView.

Цель нашей работы - сопоставить каждому узлу в XML-документе узел в TreeView и по клику в дереве выводить, например, значения атрибутов узла.

Первыое, что пришло в голову- это сделать запись вида:

type
  TNodeRecord = record
    XMLNode:  IXMLNode;
    TrNode: TTreeNode;
end;

Так, используя эту запись можно всегда найти узел XML по, например, имени узла в TreeView и наоборот.

Теперь, определим следующие типы данных и класс:

type
  PTreeView = ^TTreeView;
  PNodeRecord = ^TNodeRecord;
 
type
TNodeList = class(TList)
private
  procedure SetRecord(index: Integer; Ptr: PNodeRecord);
  function GetRecord(index: Integer): PNodeRecord;
public
  constructor Create;
  procedure Clear;
  destructor Destroy; override;
  property NodeItem[i: Integer]: PNodeRecord read GetRecord write SetRecord;
end;

В этом списке мы и будем хранить все наше "богатство". Если потребуется, то можно будет дописать, например дополнительные методы поиска по атрибутам и т.д.

Теперь непосредственно сам класс, реализующий работу с деревом и XML-документом:

type
TXMLTree = class
private
  FTreeView: PTreeView;//указатель на дерево
  FXMLDoc: IXMLDocument;//XML-документ
  FFileName: string;
  FNodeList: TNodeList;
  procedure LoadTopElements;
  procedure Recurse;
public
  function XMLNodeFromTreeText(const cText: string):IXMLNode;
  property NodeList: TNodeList read FNodeList;
  constructor Create(const aFileName:string; aTree:PTreeView);
end

На данный момент с использованием класса можно сделать следующее:

  1. Загрузить XML-документ и постоить дерево TreeView
  2. Получить список всех узлов
  3. Получить целиком (вместе с атрибутами) узел XML-документа, которому соответствует узел TreeView c текстом cText
  4. Загрузить в TreeView только узлы первого уровня.

Дерево TreeView строится при этом рекурсивно:

procedure TXMLTree.Recurse;
var iNode: IXMLNode;
 
procedure ProcessNode(Node: IXMLNode; TreeNode: TTreeNode);
var cNode: IXMLNode;
    s: string;
NodeRec: PNodeRecord;
begin
  if Node = nil then Exit;
  s:=Node.NodeName;
  TreeNode := FTreeView.Items.AddChild(TreeNode, s);
  New(NodeRec);
    with NodeRec^ do
      begin
        XMLNode:=Node;
        TrNode:=TreeNode;
      end;
    FNodeList.Add(NodeRec);
end;
cNode := Node.ChildNodes.First;
while cNode &lt;&gt; nil do
begin
  ProcessNode(cNode, TreeNode);
  cNode := cNode.NextSibling;
end;
end;
 
begin
  iNode := FXMLDoc.DocumentElement.ChildNodes.First;//стартуем с первого элемента
  while iNode &lt;&gt; nil do
    begin
      ProcessNode(iNode, nil); // Рекурсия
      iNode:=iNode.NextSibling;
    end;
end;

Можно, конечно, поругаться на рекурсию, типа опасно и т.д., но в данном случае никаких зависаний, залипаний и пр. ошибок быть не должно. Проверял на достаточно сложных документах с большим количеством уровней, узлов и т.д. - работает шустро.

Поиск узла XML-документа по тексту в TreeView осущесвляется следующим образом:

function TXMLTree.XMLNodeFromTreeText(const cText: string): IXMLNode;
var LCount: Integer;
    LList: PPointerList;
    i:integer;
begin
  LCount:= FNodeList.Count;
  LList :=FNodeList.List;
  for i := 0 to LCount - 1 do
    begin
      if PNodeRecord(LList[i])^.TrNode.Text=cText then
        begin
          Result:=PNodeRecord(LList[i])^.XMLNode;
          break;
        end;
    end;
end;

Теперь, что касается вообще работы с объектом. При построении дерева можно как угодно менять название узла в TreeView -функция поиска все равно будет работать.

Ну, а после того, как узел TreeView сопоставлен с IXMLNode - можно делать все что угодно, в т.ч. и читать атрибуты узла.

Кстати, чуть не забыл, те, кто желает ознакомиться с методами работы с приведенным в посте списком TList - приглашаю в этот пост моего блога.

-----------------------------
Если Вы всё ещё не знаете как сделать свой сайт без лишних хлопот и учили, то Вам поможет блог bezproblemweb.ru - вс, что Вам необходимо знать: выбор хостинга, регистрация домена и т.д.

Специально для женской аудитории моего блога - материалы для наращивания ногтей на любой вкус и цвет. Все, что Вам необходимо, чтобы Ваши коготки были в порядке и всегда блестели :)

Всерьез заботитесь о своем здоровье? Остеопатия - один из методов традиционной безмедикаментозной медицины должен Вас заинтересовать

-----------------------------
Понравилась статья? Тогда:
Делись! Загружай! Плюсуй!
   Отправить PDF на   
Читай ещё статьи на WebDelphi.ru

Комментарии (5)

WP_Cloudy

Ваш ответ

Внимание: Все комментарии модерируются, и это может вызвать задержку их публикации. Отправлять комментарий заново не требуется.

Пожалуйста, заключайте исходный код в тэги [code][/code].
Если код большой, то воспользуйтесь Вставкой кода на отдельной странице и оставьте в комментарии ссылку на исходник

   


Контроль протечек, Система протечки нептун