Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2013.06.16;
Скачать: [xml.tar.bz2];

Вниз

XML: Проект "ApolloSAX"   Найти похожие ветки 

 
DevilDevil ©   (2013-02-01 11:18) [0]

Доброе время суток всем

Пишу здесь, потому что посетила мою голову навязчивая идея. Я подумал, что если изложу свои мысли здесь, то вполне возможно, что из идеи в итоге выйдет достойный проект

Пара слов об XML
Я думаю ни для кого не секрет, что XML плотно засел в современные информационные технологии. Его используют везде. Раньше я видел только одно предназначение XML - файлы настроек. Однако сегодня его используют в Веб, тех же самых мессенджерах, форматы файлов стали активно строить на XML. Немалый вклад в укоренение XML на мой взгляд стала технология Office Open XML, разработанная компанией Microsoft. Да что тут говорить, даже старый добрый HTML всё чаще и чаще заменяют XHTML. Совсем недавно обнаружил, что мой любимый "MindManager" тоже использует OOXML для своих файлов.

Пара слов обо мне
Программирую 14 лет. Люблю Delphi, неплохо знаю ассемблер x86, С/C++ тоже немного знаю (2.5 года официальной работы). Моя стихия - это оптимизации и удобный пользовательский интерфейс (тоже в некотором роде оптимизация - эффективности деятельности пользователя). Имею опыт генерации и распарсивания XML/HTML с очень хорошей скоростью. Тестировали с разными парсерами - получилось что-то между pugiXML и Expat, ближе к pugi. С другой стороны парсер понимал только Ansi и Utf8, не мог обрабатывать CDATA. В общем достаточно неуниверсальный парсер

Зачем ещё один парсер
Я думаю многие со мной согласятся. Несмотря на обилие достойных SAX и DOM парсеров, вопрос идентификации элементов/атрибутов, производительности, валидации, удобства использования - по прежнему остаётся актуальным. Проект который я предлагаю сделать - максимально упрощает жизнь вышеописанную рутинную работу

В чём состоит идея
Идея проста и гениальна. В большинстве случаев, распарсивая сложный (или простой) XML, мы уже разумеется знаем его строение. По умному - если предполагается обмениваться XML, то к нему существует XSD-схема (или схема в другом формате). Для идентификации имён элементов и атрибутов мы используем различные алгоритмы, чтобы в конечном счёте строку-идентификатор преобразовать к целочисленной константе. Достаточно эффективен поиск таких идентификаторов в хеш-таблице. Но это накладные расходы: хеш-функция, поиск в массиве, коллизии, перераспределение массива, надо делать сверки строк. Лично я для подобных случаев разработал более эффективный способ. Я написал утилиту, которая имеет на входе ряд идентификаторов, а на выходе выдаёт оптимальную функцию на ЯВУ, позволяющую однозначно определять идентификаторы. К примеру если я знаю, что элемент имеет одно из имён: "sheet","row","cell","data","value","style" - то код позволяющий мне определить элемент, будет выглядеть так. TAnsiPointer - это мой внутренний тип, хранящий длину строки и указатель на её символы. Мне очень нравится :)
const
 ID_UNKNOWN = 0;
 ID_CELL = 1;
 ID_DATA = 2;
 ID_ROW = 3;
 ID_SHEET = 4;
 ID_STYLE = 5;
 ID_VALUE = 6;

// generated by "Static Serializer"
function StrToSomeType(const S: TAnsiPointer): integer;
type
 __TAnsiPointerData = packed record
 case integer of
   0: (chars: array[0..high(integer)-1] of ansichar);
   1: (words: array[0..high(integer)div 2-1] of word);
   2: (dwords: array[0..high(integer)div 4-1] of dword);
 end;
begin
 Result := ID_UNKNOWN;

 { case sensitive, ansi }
 with __TAnsiPointerData(pointer(S.Data)^) do
 case (S.Length) of
  3: if (words[0]=$6F72)and(chars[2]="w") then Result := ID_ROW;
  4: case (dwords[0]) of
       $6C6C6563: Result := ID_CELL;
       $61746164: Result := ID_DATA;
     end;
  5: case (dwords[0]) of
       $65656873: if (chars[4]="t") then Result := ID_SHEET;
       $6C797473: if (chars[4]="e") then Result := ID_STYLE;
       $756C6176: if (chars[4]="e") then Result := ID_VALUE;
     end;
 end;
end;


Но суть не в том. Суть в том, что
1) идентифицировать элементы и атрибуты можно на лету
2) генерировать целочисленные константы можно на лету
3) вся эта информация уже хранится в XSD
4) существует возможность проводить валидацию документа и преобразовывать данные к нужному формату тоже на лету. Например если ожидается число - то преобразовывать к числу, если дата - то к дате. Если нужно оставить строкой - ради бога.
5) в конкретный момент парсинга ожидается ограниченно малое количество идентификаторов: элементов/атрибутов. Это позволяет существенно сократить время идентификации очередного элемента/атрибута
6) ну и наконец, как человек таки написавший парсер, заявлю. С точки зрения производительности намного эффективнее парсить очередной элемент, когда ты знаешь, как он может называться. Это значительно эффективнее поиска скобочек, кавычек, спец знаков и тд. ... с дальнейшей их универсальной идентификацией

В целом я предлагаю разработать утилиту, которая позволяет открывать XSD-схему (или другие), выставлять им специфичные опции (например какие элементы/атрибуты пропускать или к каким типам приводить), а на выходе получать специально заточенные модули-парсеры *.pas (для Delphi/FreePascal) или *.h/*.c (для C/C++). В модулях будут объявлены все необходимые константы, а так же главная функция-парсер. Для Delphi она будет реализована в виде дампов машинного кода для платформ x86, x64, ARM. Для С/C++ будет реализация на ЯВУ, но тоже мега запутанная. Главное в этих функциях не читабильность, а стабильная эффективная работа и компилируемость.

Парсер по сути состоит из двух частей: модуль-парсер, заточенный по конкретному XSD, и один универсальный модуль, в котором будут располагаться вспомогательные функции и так же рутина для потокового чтения. Под потоковым чтением я подразумеваю эффективное чтение данных например из файла (или того же zip) и автоматическое переконвертирование в случае необходимости в нужную кодировку

На кого ориентировано
1) кому нужно обрабатывать огромные XML файлы с максимально возможной скоростью
2) кому очень хочется комфортного распарсивания с автоматической валидацией
3) кто хочет сделать DOM-чтение по конкретному XSD

Кто нужен в проект
один-два фаната XML, которые знают все его правила, знают подходы для парсинга, знают несколько эффективных реализаций
один знаток XSD который способен адекватно и в полной мере консультировать по всем особенностям схем
один-два классных специалиста, способных написать просмотрщик XSD (с возможностью выставлять наши специфические опции), с приятным и удобным пользовательским интерфейсом
один-два скептика, которые захотят на конкретных примерах доказывать, что наш парсер работает медленно и некорректно
я буду заниматься генерацией pas/h-c и вспомогательным модулем

Разумеется всё на энтузиазме
Хотя если у кого то возникнет желание разработать проект на материальной основе - буду рад продать свою идею и свой труд на его реализацию


 
DevilDevil ©   (2013-02-01 11:18) [1]

P.S.
Аполлон (Apollo) - бог света, наук, искусств и предсказаний в греческой мифологии, сын Зевса. Покровитель путешественников. На Олимпийских играх победил в беге Гермеса, а Ареса одолел в кулачном бою. "Никто из бессмертных не может сравниться по красоте с Аполлоном! Вечно молод он - высокий, стройный, золотоволосый бог". Наиболее известен в городе Дельфы (Delphi). Где одолел Пифона, основал Пифийские игры, и жил - весной и летом.


 
Sergey Masloff   (2013-02-01 11:48) [2]

дальше в XSD схеме встречается xs:anyType и?


 
DevilDevil ©   (2013-02-01 11:51) [3]

> Sergey Masloff   (01.02.13 11:48) [2]

в этом случае специфичный калбек. По аналогии со стандартными SAX-парсерами


 
DevilDevil ©   (2013-02-02 00:07) [4]

думаю проект таки будет называться ApolloXML
Почему речь вообще пошла о SAX
Дело в том, что существуют 2 основные схемы распознавания XML: SAX и DOM
Так вот, существуют различные задачи по обработке больших XML (100Мб и выше) с высокой скорость. И здесь SAX нет равных. По крайней мере не было.

И здесь родилась моя гениальная идея (да, я скромный). Что имея XSD мы можем существенно оптимизировать парсинг (сгенерировать конечный автомат), который будет автоматически определять идентификаторы элементов и атрибутов, и вызывать element_start() и attribute() уже не со строками в качестве имени, а уже с определёнными ID-константами, который определил парсер. Кроме того такой парсер (конечный автомат) очень легко может отслеживать неправильно или не в том порядке указанные элементы и атрибуты (валидация).

Потом я подумал, что значения атрибутов лучше тоже не всегда передавать строкой, а в случае определённого типа (числа, строковой константы, булеана, даты) - просто автоматически приводить данные к нужному типу и уже полученное значение передавать в калбек. Одновременно с этим вполне можно проводить валидацию значений! И это тоже будет проходить легко и непренуждённо!

Уже несколько суток я думаю следующее. Нафига вообще вызывать калбеки по атрибутам ?
Когда человек распарсивает элемент с атрибутами, элемент для него представляется некоей структурой. И XSD-утилита может генерировать описание такой структуры, и парсер будет в стеке выделять память под неё, заполнять все поля (в том числе по умолчанию), и в калбек уже передавать ID-структуры с указателем на данные структуры. Это мегаудобно. Кроме того это быстрее, чем дёргать калбек для каждого атрибута и заставлять пользователя его обрабатывать.

Ну и последние сутки я думаю, что на основе этого "SAX"-парсера, можно вполне сделать и DOM-парсер. Иначе говоря один парсер-"конечный автомат" одинаково хорошо может подходить и для SAX и для DOM. Фактически отличие только одно. Для SAX память под элементы будет выделяться в стеке, но для них будут вызываться калбеки. Для DOM память будет выделяться в пуле (такой способ менеджмента памяти) и наводить связи между Child-Parent ами. Серьёзными выигрышными сторонами такого DOM-решения по сравнению с тем же PugiXML и XML-Binding я считаю:
1) Максимально возможная производительность (из-за специально заточенной архитектуры парсера)
2) Практически бесплатная валидация (вообще это считается очень тяжёлой операцией). Но просто представьте, что вообще не надо будет заботиться о правильности введённых данных
3) Минимальное потребление памяти. Потому что не будет необходимости хранить в ОЗУ многочисленные строки
4) Супер удобство

P.S.
надо заботиться о пользователе
3 секунды значительно лучше, чем 10


 
DevilDevil ©   (2013-02-02 00:09) [5]

Кстати я накидал объявления типов. Хотя для *.h/*.c по идее будут аналоги

type
 // внутренний тип строк, хранящий указатель на символьные данные, длинну и
 // кодировку + высокоуровневые методы для извлечения строк стандартного типа
 TApolloString = object
   // todo
 end;

 // общая информация об элементе (узле)
 PApolloNodeSAX = ^TApolloNodeSAX;
 TApolloNodeSAX = object
 private
   FID: integer;
   FLevel: integer;
   FParent: PApolloNodeSAX;
   FIndex: integer;
   FUserData: pointer;
 public
   // однозначная идентификация элемента
   // для каждого элемента в XSD есть соответствующая ID-константа
   property ID: integer read FID;
   // уровень вложенности элемента
   // главный элемент имеет уровень 0, дочерние - 1
   property Level: integer read FLevel;
   // информация об элементе-отце
   // у главного элемента Parent = nil
   property Parent: PApolloNodeSAX read FParent;
   // Parent.Childs[Index] = This
   property Index: integer read FIndex;
   // любая рабочая информация, указанная пользоватем
   // главное не сохранять сюда рабочую структуру (Values)
   // потому что область действия Values ограничивается только OnNodeStart
   property UserData: pointer read FUserData write FUserData;
 end;

 // вызываемые при парсинге калбеки
 TApolloEvent = procedure() of object;
 TApolloNodeStart = function(const Node: TApolloNodeSAX; const Values: pointer): integer of object;
 TApolloNodeFinish = procedure(const Node: TApolloNodeSAX) of object;
 // структура, содержащая все необходимые калбеки
 TApolloCallbacks = record
   OnXmlBegin: TApolloEvent;
     OnNodeStart: TApolloNodeStart;
     OnNodeFinish: TApolloNodeFinish;
   OnXmlEnd: TApolloEvent;
 end;

 // продвинутый вариант элемента, используется в DOM-парсинге
 // отличается от SAX-варианта тем, что содержит все прочитанные данные (Values)
 // а так же хранит информацию о потомках и удобные методы для работы
 PApolloNodeDOM = ^TApolloNodeDOM;
 TApolloNodeDOM = object
 private
   F: record
     case Integer of
       0: (ID: integer; Level: integer; Parent: PApolloNodeDOM; Index: integer; UserData: pointer);
       1: (NodeSAX: TApolloNodeSAX);
   end;
   FValues: pointer;
   FChild: PApolloNodeDOM;
   FSibling: PApolloNodeDOM;
   procedure SetIndex(const Value: integer);
   procedure SetParent(const Value: PApolloNodeDOM);
 public
   property ID: integer read F.ID;
   property Level: integer read F.Level;
   property Parent: PApolloNodeDOM read F.Parent write SetParent;
   property Index: integer read F.Index write SetIndex;
   property UserData: pointer read F.UserData write F.UserData;
   property AsNodeSAX: TApolloNodeSAX read F.NodeSAX;

   // структура, в которой хранятся данные по элементу
   property Values: pointer read FValues;

   property Child: PApolloNodeDOM read FChild;
   property Sibling: PApolloNodeDOM read FSibling;
   {
     procedure Delete;
     property NextNode: PApolloNodeDOM read FSibling;
     property PrevNode: PApolloNodeDOM read GetPrevNode;
     property BottomChild: PApolloNodeDOM read GetBottomChild;
     property NodesCount: integer read GetNodesCount;
     property Nodes[const AIndex: integer]: PApolloNodeDOM read GetNode;
     function NodeExists(const AID: integer): boolean;
     function FindNode(const AID: integer; const recursion: boolean=false): PApolloNodeDOM;
   }
 end;


 
имя   (2013-02-02 10:52) [6]

Удалено модератором


 
KilkennyCat ©   (2013-02-02 13:17) [7]

идея стоящая. могу потом тестером побыть, создать конфликтные ситуации.


 
brother ©   (2013-02-02 13:25) [8]

идея понравилась


 
vuk ©   (2013-02-02 13:28) [9]

А с кодировками правильно работать уже научились?


 
wl ©   (2013-02-02 13:40) [10]


> vuk ©   (02.02.13 13:28) [9]

судя по первому посту этим должен заниматься отдельный модуль, что, в принципе правильно. отделение мух от котлет


 
DevilDevil ©   (2013-02-02 14:09) [11]

> KilkennyCat ©   (02.02.13 13:17) [7]

принято ;)

> brother ©   (02.02.13 13:25) [8]

спасибо

> vuk ©   (02.02.13 13:28) [9]

на 90% :)


 
Pavia ©   (2013-02-02 14:30) [12]

Поздравляю вы придумали идею 60-х годов на основе идеи 50-х годов.
Теперь по поводу ошибок.

> 6) ну и наконец, как человек таки написавший парсер, заявлю.
>  С точки зрения производительности намного эффективнее парсить
> очередной элемент, когда ты знаешь, как он может называться.
>  Это значительно эффективнее поиска скобочек, кавычек, спец
> знаков и тд. ... с дальнейшей их универсальной идентификацией

Это хорошо если у нас язык является простым, к примеру LR(1). Но в целом к XML это не относится.


> В целом я предлагаю разработать утилиту, которая позволяет
> открывать XSD-схему (или другие), выставлять им специфичные
> опции (например какие элементы/атрибуты пропускать или к
> каким типам приводить), а на выходе получать специально
> заточенные модули-парсеры *.pas (для Delphi/FreePascal)
> или *.h/*.c (для C/C++). В модулях будут объявлены все необходимые
> константы, а так же главная функция-парсер. Для Delphi она
> будет реализована в виде дампов машинного кода для платформ
> x86, x64, ARM. Для С/C++ будет реализация на ЯВУ, но тоже
> мега запутанная. Главное в этих функциях не читабильность,
>  а стабильная эффективная работа и компилируемость.

А вот с этим не согласен. Генераторы компиляторов(генератор парсера) идя конечно интересная. Но практически ихмо от неё больше вреда чем пользы.
Основным должен стать внутренний формат программы, а не внутренний формат файла.


 
vuk ©   (2013-02-02 14:44) [13]

to DevilDevil ©   (02.02.13 14:09) [11]:

> на 90% :)

Я просто посмотрел на объем исходников, например, OpenXML/ADOM ( http://www.philo.de/xml/downloads.shtml )... Так там работа со всякими кодировками и преобразованиями - это где-то треть всего объема исходников.


 
DevilDevil ©   (2013-02-02 14:48) [14]

> Pavia ©   (02.02.13 14:30) [12]

> Поздравляю вы придумали идею 60-х годов на основе идеи 50-
> х годов. Теперь по поводу ошибок.


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

> Это хорошо если у нас язык является простым, к примеру LR(1).
>  Но в целом к XML это не относится.


я даже не знаю что здесь комментировать
даже так. я не понимаю, что заставило тебя прокомментировать моё изречение

> А вот с этим не согласен. Генераторы компиляторов(генератор
> парсера) идя конечно интересная. Но практически ихмо от
> неё больше вреда чем пользы.Основным должен стать внутренний
> формат программы, а не внутренний формат файла.


реализуй

лично я считаю, что предложенная тобой идея крайне сложно формализуемая для реализации. У меня перед глазами всплывает Excel-документ в формате XML. В каком ты там виде предполагаешь хранить информацию - понять сложно. А вот получить прочитанную в XML информацию и грамотно ей распоряжаться - это уже реальная задача, и эффективная


 
xayam ©   (2013-02-02 14:49) [15]


> на 90% :)

каждый десятый символ в кракозябры ?

нет так не пойдёт :)


 
Eraser ©   (2013-02-02 15:22) [16]


> DevilDevil ©   (01.02.13 11:18) 


> В целом я предлагаю разработать утилиту, которая позволяет
> открывать XSD-схему (или другие), выставлять им специфичные
> опции (например какие элементы/атрибуты пропускать или к
> каким типам приводить), а на выходе получать специально
> заточенные модули-парсеры *.pas (для Delphi/FreePascal)
> или *.h/*.c (для C/C++). В модулях будут объявлены все необходимые
> константы, а так же главная функция-парсер. Для Delphi она
> будет реализована в виде дампов машинного кода для платформ
> x86, x64, ARM. Для С/C++ будет реализация на ЯВУ, но тоже
> мега запутанная. Главное в этих функциях не читабильность,
>  а стабильная эффективная работа и компилируемость.

это никуда не годится и будет интересно только автору парсера.
вообще я бы посмотрел в сторону возможностей RTTI современных версий делфи, есть подозрение, что там многое можно в Runtime делать.


 
DevilDevil ©   (2013-02-02 15:31) [17]

> vuk ©   (02.02.13 14:44) [13]

глобально для парсинга я вижу 2 кодировки: Ansi и Utf8
алгоритмы переконвертирования utf-16 в utf-8, или же utf-16be|utf-32|utf-32be в utf-8 - открыты и достаточно доступны

c Ansi другая песня
имеется куча различных Ansi-кодировок, но!
у меня опять таки сгенерирован код, как по имени кодировки определить её кодовую страницу: http://ideone.com/T0nqep

а уже имея номер кодовой страницы можно получить таблицы UTF-16 символов для диапазона 128..255. По крайней мере в Windows мне это удавалось, в других ОС наверняка подходящий API существуют


 
DevilDevil ©   (2013-02-02 15:36) [18]

> Eraser ©   (02.02.13 15:22) [16]
> это никуда не годится и будет интересно только автору парсера.

прям вообще никуда не годится :)
ручная обработка строк в SAX/DOM/XML-Binding - значительно лучше :))


 
Eraser ©   (2013-02-02 15:54) [19]


> DevilDevil ©   (02.02.13 15:36) [18]

мне, как и 99% пользователей все равно, как там внутри устроен парсер, но генерировать каждый раз новый pas файл при изменении структуры, это за пределами добра и зла. а если там сотня этих различных документов, что кстати, вполне себе реально в проектах, на которые заточен именно данный парсер.


 
Pavia ©   (2013-02-02 16:08) [20]


> это никуда не годится и будет интересно только автору парсера.

Ты не поверишь, но на генератор-парсеков клюнет многу народу.  Идея то что за тебя всё сделает умная машина очень заманчивая.
Так что проект будет очень популярным!
А вот когда вникаешь в суть. То выясняется:
1) приходиться очень хорошо изучать сам генератор.
2) приходиться всё описывать самому.
3) и генератор не способен работать с внутренней структурами. Так что приходиться писать конвертер, обёртку или семантический парсер.


 
DevilDevil ©   (2013-02-02 16:23) [21]

> Eraser ©   (02.02.13 15:54) [19]

я в последнее время говорю так
чтобы иметь право критиковать, даже самое малое - нужно иметь в арсенале достойную альтернативу

если тебе нужно парсить 100 разных документов, то ты будешь сам создавать 100 разных модулей, заточенных на распарсивание каждого. Только вместо готовых структур, констант и мегабыстрого парсера - ты возьмёшь стандартный парсер, и будешь для каждого узла и атрибута прописывать свою обработку со своим приведением типов. В итоге убьёшь недели труда, наделаешь ошибок и в результате получишь мизерную скорость. Это не альтернатива

> Pavia ©   (02.02.13 16:08) [20]

генератор изучать не придётся. Юзать только структуры и константы.
описывать всё самому тоже не придётся, это сделает утилита XSD --> pas

есть ли на данный момент "парсер", который сразу работает с твоими внутренними данными ? таки нет. Даже XML-Binding генерирует свою структуру. Которая крайне не оптимальна по производительности


 
Eraser ©   (2013-02-02 16:28) [22]


> DevilDevil ©   (02.02.13 16:23) [21]


> есть ли на данный момент "парсер", который сразу работает
> с твоими внутренними данными ? таки нет. Даже XML-Binding
> генерирует свою структуру. Которая крайне не оптимальна
> по производительности

на Делфи свет клином не сошелся, вообще это не лучший язык для распарсивания чего-либо, по крайней мере, нет специальной заточки под это.


 
DevilDevil ©   (2013-02-02 16:33) [23]

> Eraser ©   (02.02.13 16:28) [22]

всё правильно
на С++ рвёт всех и вся PugiXML
но он DOM
кстати появился ещё AsmXML, который выдаёт ещё лучшую производительность

Ну и потом я на Delphi имею очень хорошие скорости парсинга и генерации XML. Если умеешь пользоваться Delphi по умному - то проблем с производительностью обычно не бывает


 
Pavia ©   (2013-02-02 16:53) [24]


> описывать всё самому тоже не придётся, это сделает утилита
> XSD --> pas

И XSD она сама опишет?


> генератор изучать не придётся. Юзать только структуры и
> константы.

А структуры и константы изучать не надо?


 
DevilDevil ©   (2013-02-02 17:04) [25]

> И XSD она сама опишет?

ну для серьёзных XML (на которые в первую очередь ориентрирован парсер) всегда есть XSD.

потом есть решения, которые по имеющемуся XML сформируют схему. Я конечно не очень такому подходу доверяю, но это во многом выход. В конце концов в случае чего можно подкорректировать схему и перегенерировать парсер

> А структуры и константы изучать не надо?

Структуры соответствуют элементам в XSD. Константы тоже


 
DevilDevil ©   (2013-02-02 21:50) [26]

Таки очень нехватает человека, который разберётся в XSD схемах (и желательно разработает часть утилиты). Говорят в C# (.NET) есть какой-то интерфейс для работы с XSD


 
Узурап   (2013-02-03 03:48) [27]

Удалено модератором


 
Узурап   (2013-02-03 03:48) [28]

Удалено модератором


 
Узурап   (2013-02-03 03:49) [29]

Удалено модератором


 
DevilDevil ©   (2013-02-03 04:00) [30]

Удалено модератором


 
луеьфк   (2013-02-03 09:51) [31]

Удалено модератором
Примечание: Выражения выбираем


 
DevilDevil ©   (2013-02-03 10:19) [32]

для того чтобы понять, нужно как минимум знать:
1) что такое XML
2) как парсится XML
3) что хранится в XSD
4) почему приведённый мой код идентификации одной из 6 констант быстрее иных подходов


 
Медвежонок Пятачок ©   (2013-02-04 09:45) [33]

Только вместо готовых структур, констант и мегабыстрого парсера - ты возьмёшь стандартный парсер, и будешь для каждого узла и атрибута прописывать свою обработку со своим приведением типов.

А что если я возьму его, но не буду для каждого узла и атрибута прописывать свою обработку со своим приведением типа? И при этом все читается, и схема не нужна.

/* что давно и происходит на самом деле */


 
sniknik ©   (2013-02-04 10:14) [34]

> А структуры и константы изучать не надо?
http://delphimaster.net/view/15-1359703096/
Закон дырявых абстракций означает, к сожалению, что абстракции не так сильно упрощают нашу жизнь, как хотелось бы. Если я обучаю программистов C++, было бы здорово, если бы мне не нужно было рассказывать им про char* и арифметику указателей, а можно было сразу перейти к строкам из стандартной библиотеки темплейтов. Но в один прекрасный день они напишут "foo"+"bar", и возникнут странные проблемы, а мне придётся всё равно объяснить им, что такое char*. Или они попытаются вызвать функцию Windows с параметром типа LPTSTR и не смогут, пока не выучат char* и указатели и Юникод и wchar_t и хедерные файлы TCHAR — все то, что просвечивает через дырки в абстракциях.
и т.д.

изучать что-нибудь придется все одно.
ИМХО, лучше изучать первоисточник, и может чуть дольше, но делать правильно, с пониманием, чем тратить время на "поделку", и ладно, после основное сделать быстро, но в итоге в десять раз больше времени тратить на поиски "чудес".


 
DevilDevil ©   (2013-02-04 11:50) [35]

> Медвежонок Пятачок ©   (04.02.13 09:45) [33]
> sniknik ©   (04.02.13 10:14) [34]

Зависит от того, чего вы хотите

Вот я когда говорю о распарсивании XML вспоминаю многомегабайтные Excel-документы, которые если обрабатывать - то делать это нужно с максимальной скоростью. Есть один отчёт, выдаваемый Oracle - он весит 680Мб. И распарсить его я могу несколькими способами:
1) воспользоваться стандартным DOM-парсером типа MS XML. В этом случае софтина, использующая такой отчёт ляжет. MS XML мегамедленный и жрёт очень много памяти
2) воспользоваться альтернативным DOM-парсером. Это может быть и полюбившийся многим PugiXML, и другой интересный парсер AsmXML, и мой личный производительный DOM-парсер (вообще у меня уже есть пара реализаций парсер). В этом случае расход памяти будет около 680Мб + служебная информация... В итоге 1гб памяти только на то, чтобы иметь доступ к данным документа.
3) можно воспользоваться SAX-парсером. В этом случае не будет потрачено дополнительной памяти, но все приведения типов и отслеживания какой атрибут к какому элементу относится - придётся делать вручную
4) можно выжать производительность, если воспользоваться не SAX-парсером, а моим низкоуровневым парсером FastXmlReader (как я уже говорил - у меня есть несколько своих реализаций парсеров, одна лучше другой). В этом случае элемент представляется именем, значением и списком атрибутов. В целом можно вручную более удачно в плане производительности обработать элементы и атрибуты. Кроме того в SAX строка обычно оканчивается нулём, или не дай бог создаётся Heap-экземпляр строки (string например). А в моей реализации строка это указатель и длинна. Поэтому распознавание имени элемента и атрибута можно сделать методом, описанным в самом первом сообщении.
5) ну и наконец можно воспользоваться теоретическим SAX-парсером проекта ApolloXML. В этом случае вообще не нужно будет возиться с именами элементов и атрибутов - всё уже будет представлено константами и полями структур. При этом будет минимальное потребление памяти, и колоссальная скорость. Потому что парсер будет специально заточен под конкретные данные XML, а не универсальные, как это бывает в других парсерах

Я вообще не вижу преимуществ других парсеров над предложенным мной. Ну разве что DOM. Но опять таки, как я уже озвучил, DOM-модель можно организовать на основе этого парсера. И получится что-то типа XML-Binding, только только без строк в качестве имён и значений атрибутов


 
Медвежонок Пятачок ©   (2013-02-04 11:55) [36]

Я вообще не вижу преимуществ других парсеров над предложенным мной.

Зато я вижу.
Они (другие) есть, а твоего (наилучшего) еще нет.


 
DevilDevil ©   (2013-02-04 12:47) [37]

> Медвежонок Пятачок ©   (04.02.13 11:55) [36]

кто виноват и что делать ?


 
Sergey Masloff   (2013-02-04 14:24) [38]

DevilDevil ©   (04.02.13 11:50) [35]
>Есть один отчёт, выдаваемый Oracle - он весит 680Мб. И распарсить его я >могу несколькими способами:
>1) воспользоваться стандартным DOM-парсером типа MS XML. В этом >случае софтина, использующая такой отчёт ляжет. MS XML мегамедленный >и жрёт очень много памяти
MS XML с версии 3.2 если не ошибаюсь, с 4 - точно имеет не только DOM но и SAX парсер. Файлы размером такого порядка разбираются с приемлемой скоростью. По крайней мере у меня узкое место не разбор при работе с этими файлами.


 
DevilDevil ©   (2013-02-04 14:58) [39]

> MS XML с версии 3.2 если не ошибаюсь, с 4 - точно имеет
> не только DOM но и SAX парсер.


я знаю, что есть
его можно отнести к пункту "3"

для меня вопрос "приемлемости" не совсем корректный. Я делю задачи на простые (управляющие) и ресурсоёмкие. Часто бывает вообще без разницы каким средством воспользоваться, лишь бы попроще. А если предполагается обрабатывать большие объёмы данных - то лучше покопаться с оптимизациями. В целом у меня трепетное отношение к пользователю. Я считаю для пользователя огромная разница: 3 секунды ждать или 10

Почему я заострил своё внимание на XML - наверное потому, что для меня разбор XML - одно из узких мест. Видимо остальные моменты работают быстро. Если говорить конечно о разборе большого объёма данных

К слову. Тестировали мы в своё время парсеры. Было 40Мб XML документа, который описывает один лист Excel-я, XML взят из внутренностей *.xlsx . Программа должна была подсчитать количество элементов, атрибутов и "значений элементов" в документе. 2086127 элемента, 2629448 атрибута, 882007 значений.

Так вот Expat справился за 1,100 мск, RapidXml за 390 мск, PugiXML за 290 мск, мой FastXmlReader за 230 мск; а SAX решение от Microsoft выполнялось 13 секунд! Мой конечно был быстрее, но он не делал текстовых преобразований, а RapidXml и PugiXML - это вообще DOM.

Но это тесты на быстрых современных машинах. Для старых четвёртых пентиумов надо умножать время в разы. И потом если мы говорим о 680Мб то надо умножать на 17 (680/40)



Страницы: 1 вся ветка

Форум: "Прочее";
Текущий архив: 2013.06.16;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.69 MB
Время: 0.004 c
15-1360000237
Студент
2013-02-04 21:50
2013.06.16
Ускорение загрузки файлов. (Через FileMapping)


15-1359670971
картман
2013-02-01 02:22
2013.06.16
игра


15-1360151414
Mozart
2013-02-06 15:50
2013.06.16
php+ajax


15-1360331510
Dimka Maslov
2013-02-08 17:51
2013.06.16
Ёксель и ShellExecute


15-1360300655
alexdn
2013-02-08 09:17
2013.06.16
Косм телескоп Джеймс Вебб





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский