Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RFpro.ru: Программирование на Delphi и Lazarus


Хостинг портала RFpro.ru:
Московский хостер
Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64

РАССЫЛКИ ПОРТАЛА RFPRO.RU

Лучшие эксперты данной рассылки

Орловский Дмитрий
Статус: Академик
Рейтинг: 5162
∙ повысить рейтинг »
Boriss
Статус: Академик
Рейтинг: 2670
∙ повысить рейтинг »
cradlea
Статус: Практикант
Рейтинг: 1810
∙ повысить рейтинг »

/ КОМПЬЮТЕРЫ И СОФТ / Программирование / Delphi и Lazarus

Номер выпуска:1599
Дата выхода:26.05.2011, 18:30
Администратор рассылки:Киселёва Алёна aka Verena (Профессор)
Подписчиков / экспертов:251 / 179
Вопросов / ответов:1 / 1

Вопрос № 183230: Уважаемые эксперты! Пожалуйста, ответьте на вопрос: Нужно написать программу, принимающую на вход текстовый CSV-файл, содержащий произвольную таблицу со значениями, разделенными запятой, и преобразующую содержание этого файла в XML формат. Первая ...



Вопрос № 183230:

Уважаемые эксперты! Пожалуйста, ответьте на вопрос:
Нужно написать программу, принимающую на вход текстовый CSV-файл, содержащий произвольную таблицу со значениями, разделенными запятой, и преобразующую содержание этого файла в XML формат. Первая строка CSV файла содержит названия полей. Следующий пример показывает принцип формирования выходного XML файла:

Вход:
Город, ТипУлицы, Улица
Таганрог, улица,Ленина
Ростов, улица,Б.Садовая
Москва,проспект,Жукова

Выход:
<RECORDS>
<RECORD id=”1”>
<FIELD name=”Город” value=”Таганрог” />
<FIELD name=”ТипУлицы” value=”улица” />
<FIELD name=”Улица” value=”Ленина” />
<RECORD />
<RECORD id=”2”>
<FIELD name=”Город” value=”Ростов” />
<FIELD name=”ТипУлицы” value=”улица” />
<FIELD name=”Улица” value=”Б.Садовая” />
<RECORD />
<RECORD id=”3”>
<FIELD name=”Город” value=”Москва” />
<FIELD name=”ТипУлицы” value=”проспект” />
<FIELD name=”Улица” value=”Жукова” />
<RECORD />
</RECORDS>

P.S. Сделал так чтобы csv файл читался и данные попадали в StringGrid,потом логически понимаю что нужно построить структуру xml файла и из StringGrid выгрузить в xml,но как это сделать я не знаю...с xml никогда не работал,помогите пожалуйста
Возможно и не надо помещать данные в StringGrid,если правильно понимаю то память тратится в пустую...

Отправлен: 18.05.2011, 18:04
Вопрос задал: angel.nero (Посетитель)
Всего ответов: 1
Страница вопроса »


Отвечает Киселёва Алёна aka Verena (Профессор) :
Здравствуйте, angel.nero!
Поскольку Striker Loner пропал, отвечаю на основании его ответа из мини-форума.
Совсем не обязательно грузить данный файл в StringGrid.

Алгоритм работы будет такой:
1. Пока не кончились строки, делаем.
2. Получаем строку из файла.
3. Преобразуем её в список значений.
4. Если это самая первая строка, то принимаем её за заголовки и идем на 2.
5. Формируем узел XML файла.

Код :
procedure ExtractData(Data: string; const Values: TStrings);
{ Процедура преобразует данные хранящиеся в строке с разделителем "," в список значений}
begin
 {Данный алгоритм будет работать в Delphi 2009 и выше для младших версий
  необходимо "вручную" разбирать данную строку и заполнять список}
  Values.Clear;
  Values.LineBreak := ',';
  Values.Text := Data;
end;

function XMLRecord(XMLParentNode: IXMLNode; RecordIndex: Cardinal;
  RecordHeader, RecordValues: TStrings): IXMLNode;
{ функция возвращает ссылку на ужел в основном XML документе для данной записи
  XMLParentNode - корневой узел XML документа
  RecordIndex - порядковый новер записи
  RecordHeader - заголовок записи
  RecordValues - значения записи}
var
  XMLField: IXMLNode;
  i: Integer;
begin
  if RecordHeader.Count <> RecordValues.Count then begin
    Result := nil;
    Exit;
  end;

  Result := XMLParentNode.AddChild('RECORD');
  Result.Attributes['id'] := RecordIndex;
  for i := 0 to RecordHeader.Count - 1 do begin
    XMLField := Result.AddChild('FIELD');
    XMLField.Attributes['name'] := RecordHeader[i];
    XMLField.Attributes['value'] := RecordValues[i];
  end;
end;

procedure ConvertCSVToXML(CSVFile: TFileName; XMLDoc: TXMLDocument);
{ Процедура преобразует входящий CSVFile в  XML документ}
var
  fCSV: TextFile;
  sData: string;
  slHeader: TStringList;
  slRecord: TStringList;
  iRecordIndex: Cardinal;
begin
  slHeader := TStringList.Create;
  slRecord := TStringList.Create;
  AssignFile(fCSV, CSVFile);
  Reset(fCSV);
  if not Eof(fCSV) then begin
    XMLDoc.Active := True;
    XMLDoc.DocumentElement := XMLDoc.CreateNode('RECORDS');
    iRecordIndex := 0;
  end;
  while not Eof(fCSV) do begin
    Readln(fCSV, sData);
    if iRecordIndex = 0 then begin
      Inc(iRecordIndex);
      ExtractData(sData, slHeader);
      Continue;
    end;

    ExtractData(sData, slRecord);
    XMLRecord(XMLDoc.DocumentElement, iRecordIndex, slHeader, slRecord);
    Inc(iRecordIndex);
  end;
  CloseFile(fCSV);
  slHeader.Free;
  slRecord.Free;
end;

procedure TForm1.btnconvertClick(Sender: TObject);
begin
  lstXML.Clear;
  xmldcmnt1.Active := False;
  ConvertCSVToXML(lbledtFilename.Text, xmldcmnt1);
  lstXML.Items.Text := FormatXMLData(xmldcmnt1.XML.Text);
end;


Во вложении лежит оттестированый проект в Delphi 2010/2006 (должен пойти и на 7) с комментариями к каждой функции, за исключением ExtractData (там и так все должно быть понятно).
Теперь XML документ формируется в кодировке Windows-1251, поэтому должен нормально отображаться в Delphi 7/2006/2010.
Документ форматируется в ListBox'е для удобства чтения и оценки результата. Как необходимо форматировать документ, описано в процедуре конвертирования, поэтому сохраняемый файл будет в нужном форматировании и кодировке. Прикрепленный файл: загрузить »

-----
Эта история - не для истории, понимаешь?

Ответ отправил: Киселёва Алёна aka Verena (Профессор)
Ответ отправлен: 25.05.2011, 19:21
Номер ответа: 267380
Россия, Москва
Адрес: Москва, Солнцево
Адрес сайта: Портал Вникуда: творчество, цитаты, события.
ICQ # 230360822

Вам помог ответ? Пожалуйста, поблагодарите эксперта за это!
Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 267380 на номер 1151 (Россия) | Еще номера »
  • Отправить WebMoney:


  • Оценить выпуск »
    Нам очень важно Ваше мнение об этом выпуске рассылки!

    Задать вопрос экспертам этой рассылки »

    Скажите "спасибо" эксперту, который помог Вам!

    Отправьте СМС-сообщение с тестом #thank НОМЕР_ОТВЕТА
    на короткий номер 1151 (Россия)

    Номер ответа и конкретный текст СМС указан внизу каждого ответа.

    Полный список номеров »

    * Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи. (полный список тарифов)
    ** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
    *** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.



    В избранное