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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Парсинг... Парсинг... Парсинг... ...XML-подобного файла 
:(
    Опции темы
[EViL]
Дата 9.3.2005, 15:44 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Народ!!! Подскажите, plz, как пропарсить файл с примерно следующим содержанием: smile
Код

<config>
  <scripts enabled = "1">
    <dir>Scripts</dir>
  </scripts>
</config>

Причём мне надо просто занести все эти значения в record.
А как прочитать все эти значения?
smile
  Вверх
Satana
Дата 9.3.2005, 16:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 564
Регистрация: 15.9.2004
Где: Ставрополь, СЗ ра йон

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



не пойму тебе в какой рекорд нада ет все поместить? и каким образом? тебе только теги туда поместить нада или то что межу тегами находится?


--------------------
 Работай на себя 
www.abalentsev.com - Сайт портфолио.
www.pokushau.ru - Рецепты со всего мира.
PM MAIL WWW ICQ   Вверх
_hunter
Дата 9.3.2005, 16:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

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



возьми исходник любого парсера и переделай под свои нужды


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
[EViL]
Дата 9.3.2005, 18:59 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Satana В запись типа этой:
Код

var
  Config: record
    Enabled: boolean;
    Dir: string;
  end;

_hunter Где бы ещё парсер взять... На torry.net только XML, причем используют TTreeView как-то по хитрому... smile

smile
  Вверх
maxim1000
Дата 9.3.2005, 19:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



насколько я знаю, в сандартном наборе есть TXMLDocument...

Это сообщение отредактировал(а) maxim1000 - 9.3.2005, 19:31


--------------------
qqq
PM WWW   Вверх
Satana
Дата 10.3.2005, 00:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 564
Регистрация: 15.9.2004
Где: Ставрополь, СЗ ра йон

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



ну если такого вида как ты написал, то тебе нада юзать pos.
Читаешь построчно файл и в каждой строке ищешь вхождение <scripts, если нашел делаешь следущее идешь построчно до кавчки и смотришь что стоит после 0 или 1.
После этого ищешь вхождение <dir> и посимвольно в строчную переменную читаешь до того момента как тебе встретится символ <

Вот собственно и все.

ЗЫ ет если тебя алгоритм интересовал smile

Это сообщение отредактировал(а) Satana - 10.3.2005, 00:10


--------------------
 Работай на себя 
www.abalentsev.com - Сайт портфолио.
www.pokushau.ru - Рецепты со всего мира.
PM MAIL WWW ICQ   Вверх
Guest
Дата 10.3.2005, 13:11 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











smile
Чё-то не выходит smile smile smile
Парсинг - не моё призвание... smile
  Вверх
Satana
Дата 10.3.2005, 14:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 564
Регистрация: 15.9.2004
Где: Ставрополь, СЗ ра йон

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



Ну жди до вечера попробую слабать конкретно под этот пример тебе пример smile


--------------------
 Работай на себя 
www.abalentsev.com - Сайт портфолио.
www.pokushau.ru - Рецепты со всего мира.
PM MAIL WWW ICQ   Вверх
[EViL]
Дата 10.3.2005, 19:12 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Тут на меня снизошло вдохновение... Создал сам)) smile
Работает почти "на отлично" smile
Вот только мне не нравится как реализована запись, а переделывать просто нет времени.
Отладьте, плз, код.
Код

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.


ZML - ZeroDivide Markup Language - в честь моего проекта.
Как использовать объект (чтобы сразу проверить работоспособность):
Код

program ZDM_Demo;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  ZD_ZMLParser in 'ZD_ZMLParser.pas';

const
  Key = 'Width';

var
  Parser: TZMLParser;

begin
  Parser := TZMLParser.Create('file.zml');
  WriteLn(Parser.ReadString('Graphics', Key));
  Parser.WriteString('Graphics', Key, '1024');
  Parser.UpdateZMLFile;
  WriteLn(Parser.ReadString('Graphics', Key));
  Parser.Free;
  ReadLn;
end.


Заранее спасибо!
  Вверх
[EViL]
Дата 10.3.2005, 19:18 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Хотя свой пример всё равно давай.
  Вверх
<Spawn>
Дата 10.3.2005, 20:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Как уже было сказано, для этого существует TXMLDocument и не нужно изобретать велосипед!

Все работает примерно так(Конкретно для твоего случая, если возможны другие варианты, то нужно либо циклом, либо рекурсией перебирать элементы и извлекать нужные занчения):

Код

uses XMLDom, XMLDoc;

...

type

  TConfig = record
    Enabled: Boolean;
    Dir: string;
  end;

...

procedure TForm1.Button1Click(Sender: TObject);
var
  Document: TXMLDocument;
  Config: TConfig;
begin
  with TXMLDocument.Create do
  try
    LoadFromFile('FileName.xml');
    Active := True;
    with Config do
    begin
      Enabled := DOMDocument.childNodes[0].childNodes[0].attributes[0].nodeValue;
      Dir := DOMDocument.childNodes[0].childNodes[0].childNodes[0].childNodes[0].nodeValue;
    end;
  finally
    Free;
  end;
end;



--------------------
"Для некоторых людей программирование является такой же внутренней потребностью, подобно тому, как коровы дают молоко, или писатели стремятся писать" - Николай Безруков.
PM MAIL ICQ   Вверх
Satana
Дата 10.3.2005, 22:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 564
Регистрация: 15.9.2004
Где: Ставрополь, СЗ ра йон

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



ну вот мой пример:
Код

var
  Form1: TForm1;
  f:text;
  tip:Config;
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
i,j:byte;
dir_pos:word;
dir:string[255];
str:string;
s:string[1];
m:byte;
begin
assignfile(f,'111.txt');
reset(f);
while not eof(f) do
begin
readln(f,str);
if pos('<scripts',str)<>0 then
  begin
    for i:=1 to length(str) do
      begin
      if str[i]='"' then s:=str[i+1];
      if s='1' then
        begin
          tip.Enabled:=true;
          break;
        end;
      end;
  end;
  j:=1;
  i:=0;
dir_pos:=pos('<dir>',str);
m:=dir_pos+5;
if dir_pos<>0 then
  begin
    for i:=m to length(str) do
    if str[i]<>'<' then
      begin
        dir[j]:=str[i];
        j:=j+1;
      end
      else break;
    tip.Dir:=dir;
  end;
end;
end;




--------------------
 Работай на себя 
www.abalentsev.com - Сайт портфолио.
www.pokushau.ru - Рецепты со всего мира.
PM MAIL WWW ICQ   Вверх
[EViL]
Дата 11.3.2005, 18:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Спасибо!
А можешь мой модуль пофиксить?
PM MAIL WWW ICQ   Вверх
Satana
Дата 11.3.2005, 19:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 564
Регистрация: 15.9.2004
Где: Ставрополь, СЗ ра йон

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



[EViL] Да ты знаешь я в создании классов и всей етой хрени не очень то силен smile


--------------------
 Работай на себя 
www.abalentsev.com - Сайт портфолио.
www.pokushau.ru - Рецепты со всего мира.
PM MAIL WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

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

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

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

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


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

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


 




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


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

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