По просьбе читателей блога, решил объединить две статьи про работу с XML-файлами в TreeView и выложить полный исходник программы, представляющей XML-файл любой сложности в виде TreeView.
Итак, нам потребуется XML-файл (желательно большой). В качестве «подопытного кролика» я выбрал XML-файл, который используется в популярном плеере LightAlloy при загрузке скина. Наша задача — загрузить XML в TreeView и представить название всех узлов в понятном для пользователя виде, т.е. не просто узел в именем tbnButton и т.д., а в виде «Кнопка «Воспроизведение»» и т.д.
Основные типы данных, используемых при работе с XML-документом я описывал в этом посте, в нем же вы можете посмотреть и небольшой пример работы с классом.
Остается только «научить» программу правильно «распознавать» имена узлов.
Я не стал выдумывать ничего особенного, а просто проанализировал содержимое документа и создал несколько константных массивов с именами элементов документа:
//названия кнопок const BtnNames :array [1..35,1..2] of string =( ('LAInfo','О программе'), ('AlwaysOnTop','Поверх всех окон'), ('Close','Закрыть'), ('Maximize','Развернуть во весь экран'), ('Minimize','Минимизаровать'), ('Play','Воспроизведение'), ('FrameForw','Кадр вперед'), ('PlaybackSpeed','Промотать назад'), ('Open','Открыть'), ('NextTrack','Следующий трек'), ('PlayList','Список воспроизведения'), ('PreviousTrack','Предыдущий трек'), ('Mute','Отключить звук'), ('ShowEQ','Показать эквалайзер'), ('SoundOpt','Настройки звука'), ('VideoOpt','Настройки видео'), ('ScreenShot','Сохранить кадр'), ('SubtitlesOpt','Настройки субтитров'), ('ShowGraph','Зависимости'), ('FileInfo','Информация о файле'), ('Preferences','Настройки'), ('DefaultSize','Первоначальный размер'), ('PlaySelected','Воспроизвести выбранный файл'), ('AddFiles','Добавить файлы'), ('DeleteFiles','Удалить файлы'), ('MoveUp','Поднять вверх'), ('Shuffle','Случайный порядок воспроизведения'), ('Bookmarks','Закладки'), ('Repeat','Повтор'), ('AddFolder','Добавить папку'), ('ClearList','Очистить список'), ('MoveDown','Опустить вниз'), ('Report','Таблица по списку'), ('SaveList','Сохранить список'), ('FullScreen','Во весь экран')); //название корневых элементов документа RootElements : array [1..7,1..2] of string = (('VideoMode','Режим видео'), ('AudioMode','Режим аудио'), ('Skin','Скин'), ('Menu','Меню'), ('MainWindow','Главное окно'), ('ExtPlayList','Раскрытый список воспроизведения'), ('Equalizer','Эквалайзер')); //название других элементов скина OtrherElements: array [1..13,1..2]of string=(('Border','Бордюр окна'), ('CaptionPanel','Панель заголовка'), ('CaptionText','Текст заголовка'), ('ControlPanel','Панель управления'), ('ChildPanel','Дочерняя панель'), ('Track','Бегунок'), ('TimeLine','Линия воспроизведения'), ('Clock','Часы'), ('PlayTime','Время воспроизведения'), ('PlayList','Список воспроизведения'), ('Panel','Панель'), ('ControlsPanel','Панель управления'), ('PlayListPanel','Панель списка воспроизведения'));
и написал простенькую функцию перевода названия узла в человекопонятный вид:
function SysBtnNameToHuman(const SysName: string):string; var i:integer; begin Result:=''; for I := 1 to High(BtnNames) do begin if LowerCase(BtnNames[i,1])=LowerCase(SysName) then begin Result:='Кнопка "'+BtnNames[i,2]+'"'; break; end; end; if Length(Result)=0 then begin for I := 1 to High(RootElements) do begin if LowerCase(RootElements[i,1])=LowerCase(SysName) then begin Result:=RootElements[i,2]; break; end; end; end; if Length(Result)=0 then begin for I := 1 to High(OtrherElements) do begin if LowerCase(OtrherElements[i,1])=LowerCase(SysName) then begin Result:=OtrherElements[i,2]; break; end; end; end; if Result='' then end;
Теперь создаем приложение, размещаем на главной форме Листинг главного модуля программы:
unit SEmain; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, ComCtrls, StdCtrls,XMLTree, sTreeView; type TForm5 = class(TForm) TreeView1: TTreeView; procedure FormCreate(Sender: TObject); procedure ToolButton1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form5: TForm5; XMLTree: TXMLTree; implementation uses Skins; {$R *.dfm} procedure TForm5.FormCreate(Sender: TObject); begin XMLTree:=TXMLTree.Create('Skin.xml',@TreeView1); TreeView1.AutoExpand:=true; end; procedure TForm5.ToolButton1Click(Sender: TObject); begin XMLTree.SaveTreeToXML; end; end.
Запускаем приложение и видим:
Ну и, как и обещал, все исходники и необходимые файлы для представленного примера:
надо будет глянуть… давно хотел разобраться как из дельфи xml разбирать, но то лень, то некогда :)
В исходнике все написано с использованием стандартных модулей, а вообще удобная штука NativeXML
Всё работает, но если взять например content.xml из документа опенофиса, то на некоторых компьютерах работает, а на некоторых вылетает ошибка:
—————————
Laskineditor
—————————
DTD запрещен.
Line: 2
<!DOCTYPE office:document-content PUBLIC.
—————————
как бы её избежать?
Скачал и запустил Ваш пример. Все работает. Запустил на другом XML файле — вместо названий стоят …… Подскажите в чем дело?
Скрипт не работает половина использованных файлов в uses нету.