Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Парсинг!!! ... некоего файла типа INI 
:(
    Опции темы
[EViL]
  Дата 20.3.2005, 21:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 10.3.2005
Где: Екатеринбург

Репутация: 1
Всего: 1



Мне надо прочитать настройки из XML - подобного (именно подобного!!!) файла.
Например,
Код

<graphics>
  <width>1024</width>
  <height>768</height>
  <antialiasing>true</antialiasing>
</graphics>
<sound>
  <volume>100</volume>
</sound>


Для этих целей я создал модуль, который работает наподобие TIniFile:
Код

unit ZD_ZMLParser;

interface

uses
  SysUtils, Classes;

type
  TZMLParser = class
    private
      Data: TStringList;
      _ZMLFileName: string;
      function _Read(const ASection, AKey: string): string;
      procedure _Write(ASection, AKey, AValue: string);
    public
      constructor Create(const AZMLFileName: string);
      function ReadString(const ASection, AKey: string): string;
      function ReadInteger(const ASection, AKey: string): integer;
      function ReadBoolean(const ASection, AKey: string): boolean;
      procedure WriteString(const ASection, AKey: string; AValue: string);
      procedure WriteInteger(const ASection, AKey: string; AValue: integer);
      procedure WriteBoolean(const ASection, AKey: string; AValue: boolean);
      procedure UpdateZMLFile;
      destructor Destroy; override;
  end;

implementation

function TwoSideTrim(AString: string): string;
begin
  Result := TrimLeft(TrimRight(AString));
end;

function GetCharCount(AString: string; AChar: char): integer;
var
  _Index: integer;
begin
  _Index := 0;
  repeat
    Inc(_Index);
  until AString[_Index] <> AChar;
  Result := _Index;
end;

function FillStr(AChar: char; ACount: integer): string;
var
  _Index: integer;
begin
  for _Index := 0 to ACount do Result := Result + AChar;
end;

constructor TZMLParser.Create(const AZMLFileName: string);
begin
  Data := TStringList.Create;
  if FileExists(AZMLFileName) then Data.LoadFromFile(AZMLFileName);
  _ZMLFileName := AZMLFileName;
end;

function TZMLParser._Read(const ASection, AKey: string): string;
var
  _Data: string;
  _Index, _SectionBegin, _SectionEnd: integer;
begin
  _SectionBegin := -1;
  _SectionEnd := -1;
  for _Index := 0 to Data.Count - 1 do begin
    _Data := TwoSideTrim((Data[_Index]));
    if Pos('<' + LowerCase(ASection) + '>', LowerCase(_Data)) = 1 then
      _SectionBegin := _Index;
    if Pos('</' + LowerCase(ASection) + '>', LowerCase(_Data)) = 1 then begin
      _SectionEnd := _Index;
      Break;
    end;
  end;
  for _Index := _SectionBegin + 1 to _SectionEnd - 1 do begin
    _Data := TwoSideTrim((Data[_Index]));
    if Pos('<' + LowerCase(AKey) + '>', LowerCase(_Data)) = 1 then begin
      Delete(_Data, 1, Length('<' + AKey + '>'));
      Delete(_Data, Length(_Data) - Length('</' + AKey + '>') + 1, Length('</' + AKey + '>'));
      Result := _Data;
      Break;
    end;
  end;
end;

procedure TZMLParser._Write(ASection, AKey, AValue: string);
var
  _Data: string;
  _Index, _SectionBegin, _SectionEnd: integer;
begin
  _SectionBegin := -1;
  _SectionEnd := -1;
  ASection := LowerCase(ASection);
  AKey := LowerCase(AKey);
  if _Read(ASection, AKey) = '' then begin
    if Data.Count <> 0 then begin
      for _Index := 0 to Data.Count - 1 do begin
        _Data := TwoSideTrim(Data[_Index]);
        if Pos('<' + LowerCase(ASection) + '>', LowerCase(_Data)) = 1 then
          _SectionBegin := _Index;
        if Pos('</' + LowerCase(ASection) + '>', LowerCase(_Data)) = 1 then begin
          _SectionEnd := _Index;
          Break;
        end;
      end;
      if _SectionBegin = -1 then begin
        Data.Add('<' + ASection + '>');
        Data.Add(Format('  <%s>%s</%s>', [AKey, AValue, AKey]));
        if _SectionEnd = -1 then
          Data.Add('</' + ASection + '>');
      end;
    end else begin
      Data.Add('<' + ASection + '>');
      Data.Add(Format('  <%s>%s</%s>', [AKey, AValue, AKey]));
      Data.Add('</' + ASection + '>');
    end;
  end else begin
    for _Index := 0 to Data.Count - 1 do begin
      _Data := TwoSideTrim(Data[_Index]);
      if Pos('<' + LowerCase(ASection) + '>', LowerCase(_Data)) = 1 then
        _SectionBegin := _Index;
      if Pos('</' + LowerCase(ASection) + '>', LowerCase(_Data)) = 1 then begin
        _SectionEnd := _Index;
        Break;
      end;
    end;
    for _Index := _SectionBegin + 1 to _SectionEnd - 1 do begin
    _Data := TwoSideTrim((Data[_Index]));
    if Pos('<' + LowerCase(AKey) + '>', LowerCase(_Data)) = 1 then
      Data[_Index] := Format('%s<%s>%s</%s>', [FillStr(' ', GetCharCount(_Data, ' ')), AKey, AValue, AKey]);
    end;
  end;
end;

function TZMLParser.ReadString(const ASection, AKey: string): string;
begin
  Result := _Read(ASection, AKey);
end;

function TZMLParser.ReadInteger(const ASection, AKey: string): integer;
var
  _Result: integer;
begin
  if TryStrToInt(_Read(ASection, AKey), _Result)
    then Result := _Result
    else Result := 0;
end;

function TZMLParser.ReadBoolean(const ASection, AKey: string): boolean;
var
  _Result: string;
begin
  _Result := Trim(LowerCase(_Read(ASection, AKey)));
  if (_Result = 'true') or (_Result = 'yes') or (_Result = '1')
    then Result := true
    else Result := false;
end;

procedure TZMLParser.WriteString(const ASection, AKey: string; AValue: string);
begin
  _Write(ASection, AKey, AValue);
end;

procedure TZMLParser.WriteInteger(const ASection, AKey: string; AValue: integer);
begin
  _Write(ASection, AKey, IntToStr(AValue));
end;

procedure TZMLParser.WriteBoolean(const ASection, AKey: string; AValue: boolean);
begin
  case AValue of
    true: _Write(ASection, AKey, 'true');
    false: _Write(ASection, AKey, 'false');
  end;
end;

procedure TZMLParser.UpdateZMLFile;
begin
  Data.SaveToFile(_ZMLFileName);
end;

destructor TZMLParser.Destroy;
begin
  inherited Destroy;
  Data.Free;
end;

end.


Что-то мне не нравится, как он работает, а на отладку просто нет времени!
Помогите, ибо на вас последняя надежда!
PM MAIL WWW ICQ   Вверх
Vit
Дата 20.3.2005, 23:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Vitaly Nevzorov
****


Профиль
Группа: Экс. модератор
Сообщений: 10964
Регистрация: 25.3.2002
Где: Chicago

Репутация: 48
Всего: 207



Почему XML подобный? Это самый настоящий XML - будет читаться стандартными парсерами


--------------------
With the best wishes, Vit
I have done so much with so little for so long that I am now qualified to do anything with nothing
Самый большой Delphi FAQ на русском языке здесь: www.drkb.ru
PM MAIL WWW ICQ   Вверх
[EViL]
Дата 21.3.2005, 06:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 10.3.2005
Где: Екатеринбург

Репутация: 1
Всего: 1



Нет, не будет. Смотри тогда как он должен выглядить, чтобы его читали НОРМАЛЬНЫЕ парсеры (типа IE):
Код

<xml>
  <graphics>    
    <width>1024</width>    
    <height>768</height>    
    <antialiasing>true</antialiasing>    
  </graphics>    
  <sound>    
    <volume>100</volume>    
  </sound>
</xml>


Помогите пофиксить в парсере (выше) процедуру записи!
PM MAIL WWW ICQ   Вверх
Vit
Дата 21.3.2005, 06:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Vitaly Nevzorov
****


Профиль
Группа: Экс. модератор
Сообщений: 10964
Регистрация: 25.3.2002
Где: Chicago

Репутация: 48
Всего: 207



Цитата
, 20.3.2005,  21:12]Нет, не будет. Смотри тогда как он должен выглядить, чтобы его читали НОРМАЛЬНЫЕ парсеры (типа IE):


Ну в общем то да, я заметил что не хватает общего тэга... Но проще считать файл, доставить <xml> в начало и в конец и загнать в стандартный парсер...


--------------------
With the best wishes, Vit
I have done so much with so little for so long that I am now qualified to do anything with nothing
Самый большой Delphi FAQ на русском языке здесь: www.drkb.ru
PM MAIL WWW ICQ   Вверх
[EViL]
Дата 21.3.2005, 13:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 10.3.2005
Где: Екатеринбург

Репутация: 1
Всего: 1



Ок, хорошо, допустим доствили <xml> в начало и конец.
Я не понимаю как пользоваться парсером (покажи пример хотя бы TXMLDocument, а то там всё очень сложно).
PM MAIL WWW ICQ   Вверх
Vit
Дата 21.3.2005, 16:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Vitaly Nevzorov
****


Профиль
Группа: Экс. модератор
Сообщений: 10964
Регистрация: 25.3.2002
Где: Chicago

Репутация: 48
Всего: 207





--------------------
With the best wishes, Vit
I have done so much with so little for so long that I am now qualified to do anything with nothing
Самый большой Delphi FAQ на русском языке здесь: www.drkb.ru
PM MAIL WWW ICQ   Вверх
<Spawn>
Дата 22.3.2005, 17:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Око кары:)
****


Профиль
Группа: Экс. модератор
Сообщений: 2776
Регистрация: 29.1.2003
Где: Екатеринбург

Репутация: 44
Всего: 64



[EViL] Примерно так:

Код

uses XMLDoc, XMLDom ...;

procedure TForm1.Button1Click(Sender: TObject);
begin
  with TXMLDocument.Create(Self) do
  try
    LoadFromFile('FileName.xml');
    Active := True;
    ShowMessage(Format('Root node: name - %s, value - %s', [(DOMDocument as IDOMNode).nodeName, (DOMDocument as IDOMNode).nodeValue]));
    //Ну и далее все подветки являются типичным деревом - доступ к ним можешь получить так (DOMDocument as IDOMNode).childNodes[n-ое значение]
    //Приводить к IDOMNode не обязательно - я сделал лишь для того, чтобы показать DOMDocument представляет из себя корневой элемент, так как у тебя не полноценный XML файл то инструкций препроцессора(типа <?xml version="1.0"?>) в нем не будет, т.е. корень один
  finally
    Free;
  end;
end;


Это сообщение отредактировал(а) <Spawn> - 22.3.2005, 17:32


--------------------
"Для некоторых людей программирование является такой же внутренней потребностью, подобно тому, как коровы дают молоко, или писатели стремятся писать" - Николай Безруков.
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0512 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.