Модераторы: Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [C++&XML] Парсинг, Оптимальный вариант чтения из файла 
V
    Опции темы
DubrovinAV
Дата 24.10.2007, 16:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



 Есть задача пропарсить XML файл. Как лучше читать файл для увеличения быстродействия и более удобного анализа(причем размер файла неизвестен)
  • Посимвольно
  • По одному значащему элементу(пример "<", "name"). Собственно вытекает из первого
  • Блоком загружать в память и из нее анализировать(если да то какого объема делать блок)
  • Полностью загрузить файл в память и оттуда его анализировать(если да то для хранения использовать объект класса string?->если да то какой объем он сможет хранить, если не так, то как smile  )
  • Другие более оптимальные варианты. Какие?

Спасибо.

PM MAIL   Вверх
zkv
Дата 24.10.2007, 18:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


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

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



Цитата(DubrovinAV @  24.10.2007,  16:56 Найти цитируемый пост)
Другие более оптимальные варианты. Какие?

использовать готовые отлаженные решения. 
Вроде в бусте что-то было.
PM MAIL   Вверх
DubrovinAV
Дата 25.10.2007, 18:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Извините, но вроде бы было а может и не было это, согласитесь, не ответ.

Поправлюсь
Цитата

 Как лучше читать файл для увеличения быстродействия и более удобного анализа


средствами стандартных библиотек. Поскольку пишу в с++ и код желательно что бы был переносимым использовать буду потоки ifstream и ofstream.

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

Извините за прямоту...
PM MAIL   Вверх
SenkraD
Дата 26.10.2007, 13:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



1. 
> Полностью загрузить файл в память и оттуда его анализировать
> (если да то для хранения использовать объект класса string? - 
> если да то какой объем он сможет хранить, если не так, то как   )

думаю, загрузить гиговый файл не проблемно или даже больше - ведь
допустимый размер, кажись, определяется доступной памятью процесса, 
а это кажись около 4 гигов на 32-разрядном проце

2. Если файлы не большие, можете попробовать использовать регулярки
    (у меня так пыхники знакомые не большие файлы парсят)

3. Посмотрите исходные коды готовых и отлаженных решений и выберите
    свою золотую середину.


А вообще, выбор того или иного способа зависит от задачи: мне в своё время
нужен был парсер для небольших файлов (я ими с web-сервером общался) и я
для решения этой проблемы написал простой до крика парсер (код парсера прилагаю):
Код

// header
//---------------------------------------------------------------------------

#ifndef PosterDataParserH
#define PosterDataParserH

class TDataParser {
private:
        char *buffer;
public:
        int getStartTagOffset(char *name);
        int getStopTagOffset(char *name);
        int CreateNode(char *owner, char *name);
        int CreateNode(char *owner, char *name, char *value);
        int CreateNode(char *owner, char *name, int value);
        int getValue(char *name, char *value, int size);
        char *getBuffer();
        TDataParser();
        TDataParser(char *data);
        ~TDataParser();
};


//---------------------------------------------------------------------------
#endif

// cpp
//---------------------------------------------------------------------------


#pragma hdrstop
#include <string.h>
#include <stdio.h>

#include "PosterDataParser.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

//---------------------------------------------------------------------------
TDataParser::TDataParser() {
        char *Header = "<Data></Data>";
        buffer = new char[strlen(Header) + 1];
        strcpy(buffer, Header);
}

//---------------------------------------------------------------------------
TDataParser::TDataParser(char *data) {
        buffer = new char[strlen(data) + 1];
        strcpy(buffer, data);
}


//---------------------------------------------------------------------------
int TDataParser::getStartTagOffset(char *name) {
        char *str = new char [strlen(name) + 10];
        strcpy(str, "<");
        strcat(str, name);
        strcat(str, ">");
        int str_len = strlen (str);
        char * substr = strstr(buffer, str);
        delete str;
        if(!substr) return -1;
        return (strlen(buffer) - strlen(substr) + str_len);
}

//---------------------------------------------------------------------------
int TDataParser::getStopTagOffset(char *name) {
        char *str = new char [strlen(name) + 10];
        strcpy(str, "</");
        strcat(str, name);
        strcat(str, ">");
         char * substr = strstr(buffer, str);
        delete str;
        if(!substr) return -1;
        return (strlen(buffer) - strlen(substr));
}

//---------------------------------------------------------------------------
int TDataParser::CreateNode(char *owner, char *name) {
        int start = getStartTagOffset(owner);
        int stop = getStopTagOffset(owner);

        if((start < 0) || (stop < 0)) return -1;
        int BufferSize = strlen(buffer) + strlen(name) * 2 + 0xFF;
        char * new_buffer = new char[BufferSize];
        memset(new_buffer, 0x00, BufferSize);
        strncpy(new_buffer, buffer, start);
        strcat(new_buffer, "<");
        strcat(new_buffer, name);
        strcat(new_buffer, ">");
        strcat(new_buffer, "</");
        strcat(new_buffer, name);
        strcat(new_buffer, ">");
        strcat(new_buffer, buffer + start);
        delete [] buffer;
        buffer = new_buffer;
        return 1;
}

//---------------------------------------------------------------------------
int TDataParser::CreateNode(char *owner, char *name, char * value) {
        int start = getStartTagOffset(owner);
        int stop = getStopTagOffset(owner);

        if((start < 0) || (stop < 0)) return -1;
        int BufferSize = strlen(buffer) + strlen(name) * 2 + strlen(value) + 0xFF;
        char * new_buffer = new char[BufferSize];
        memset(new_buffer, 0x00, BufferSize);
        strncpy(new_buffer, buffer, start);
        strcat(new_buffer, "<");
        strcat(new_buffer, name);
        strcat(new_buffer, ">");
        strcat(new_buffer, value);
        strcat(new_buffer, "</");
        strcat(new_buffer, name);
        strcat(new_buffer, ">");
        strcat(new_buffer, buffer + start);
        delete [] buffer;
        buffer = new_buffer;
        return 1;
}

//---------------------------------------------------------------------------
int TDataParser::CreateNode(char *owner, char *name, int value) {
        int start = getStartTagOffset(owner);
        int stop = getStopTagOffset(owner);

        if((start < 0) || (stop < 0)) return -1;
        char str[0xFF];
        sprintf(str, "%d", value);
        int BufferSize = strlen(buffer) + strlen(name) * 2 + strlen(str) + 0xFF;
        char * new_buffer = new char[BufferSize];
        memset(new_buffer, 0x00, BufferSize);
        strncpy(new_buffer, buffer, start);
        strcat(new_buffer, "<");
        strcat(new_buffer, name);
        strcat(new_buffer, ">");
        strcat(new_buffer, str);
        strcat(new_buffer, "</");
        strcat(new_buffer, name);
        strcat(new_buffer, ">");
        strcat(new_buffer, buffer + start);
        delete [] buffer;
        buffer = new_buffer;
        return 1;
}


//---------------------------------------------------------------------------
int TDataParser::getValue(char *name, char *value, int size) {
        int start = getStartTagOffset(name);
        int stop = getStopTagOffset(name);

        if((start < 0) || (stop < 0)) return -1;
        if(size < (stop - start) + 1) return -1;
        memset(value, 0x00, (stop - start) + 1);
        strncpy(value, buffer + start, stop - start);
        return 1;
}

//---------------------------------------------------------------------------
char *TDataParser::getBuffer() {
        return buffer;
}

//---------------------------------------------------------------------------
TDataParser::~TDataParser() {
        delete buffer;
}



--------------------
 Имеющий язык - да не убоится спросить! 
user posted image
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

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

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


 




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


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

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