Впоследствии, планирую довести его до ума и прикрутить иерархическую структуру.
В данный момент кирпич имеет форму модуля с тремя публичными процедурами, вывод осуществляется массивом пользовательского типа.
В дальнейшем это будет класс, с объектами, событиями и методами.
Тип TagType -- в нем хранится имя тэга, количество его параметров и его атрибуты (в массивах Fields и Values), для атрибутов без параметров (типа атрибута nowrap тэга table) в поле Value указан vbNullChar.
Тип TagTypes -- в нем хранится массив ("коллекция") тэгов.
Принцип хранения следующий.
Индекс элемента -- порядковый номер тэга. Элементы хранятся в том порядке, в котором они записаны в HTML-файле. У элемента есть свойство Last, это номер элемента, на котором действие тэга заканчивается. Для обычных тэгов эти два числа всегда равны. Для тэгов-контейнеров значение Last равно индексу последнего тэга, входящего в тэг-контейнер.
Эти два свойства позволяют выстроить иерархическую структуру тэгов. Принцип построения такой структуры довольно прост:
1) Если Last = Index, значит тэг не имеет вложенных элементов;
2) Если Last > Index, значит тэг является узлом дерева и все элементы с индексами Index+1...Last являются его потомками. Повторяя п.2 рекурсивно можно получить полное дерево тэгов.
Описание свойств элемента:
Last - указатель на последний вложенный элемент.
Name - название тэга (в верхнем регистре)
TagDisabled - флаг, указывающий что тэг отключен (его имя начинается с !), либо тэг является комментарием (имя равно "!--").
TagPosStart - позиция начала тэга, нумерация начинается с единицы.
TagPosEnd - позиция конца тэга, нумерация начинается с единицы.
TagOpen - тэг является парным и у него имеется открывающий тэг.
TagOpenPosStart - позиция начала открывающего тэга (позиция на символ <).
TagOpenPosEnd - позиция конца открывающего тэга (позиция на символ >).
TagClose - тэг является парным и у него имеется закрывающий тэг.
TagClosePosStart - позиция начала закрывающего тэга.
TagClosePosEnd - позиция конца закрывающего тэга.
TagValue - флаг, указывающий что у парного тэга имеется значение (текст между открывающим и закрывающим тэгом).
TagValuePosStart - позиция начала значения.
TagValuePosEnd - позиция конца значения.
Text - текст значения тэга; заполняется если была указана опция StoreText (игнорируются все тэги, упрощаются специальные символы, убираются дополнительные пробелы).
Attributes - атрибуты (параметры) тэга; заполняется, если была указана опция AutoParseTag.
Имеется три основных функции.
ParseHTML(HTML As String, ByRef Tags() As TagsType, Optional ByVal AutoParseTag As Boolean = False, Optional ByVal StoreText As Boolean = False)
Основная функция, осуществляющая разбор HTML-документа.
Исходный текст HTML-документа передается в HTML (значение переменной не изменяется в процедуре), вывод осуществляется в массив Tags(), все указатели в этом массиве ссылаются на HTML.
ParseTag(TagHTML As String, ByRef Tag As TagType, Optional ByVal CompactAttributes As Boolean = False)
Функция, осуществляющая разбор конкретного тэга. Текст тэга передается в HTML (значение переменной не изменяется в процедуре), вывод осуществляется в переменную Tag. Если параметр CompactAttributes будет задан, то одинаковые атрибуты будут выведены только один раз, использовано будет последнее значение.
StripHTML(ByVal HTML As String, Optional ByVal StripEntities As Boolean = True, Optional ByVal StripTags As Boolean = True, Optional ByVal StripSpaces As Boolean = True, Optional ByVal StripLineFeeds As Boolean = False) As String
Функция, вырезающая из HTML-текста указанную информацию. При задании StripEntities все элементы типа > и других будут заменены на свои значения. При указании StripTags будут вырезаны все тэги, останется только текст внутри тэгов. При указании StripSpaces будут вырезаны все дополнительные пробелы (пробелами считаются также символы табуляции и перевода строки), 2 и более пробела будут объединены в один. При указании StripLineFeeds в качестве пробелов будут рассмотрены и тэги <P>, <BR> и <HR>.
В процедуре ParseHTML автоматически осуществляется разбор тэгов (загрузка атрибутов тэгов) и загрузка текста тэга. Кроме того, осуществляется отладочный вывод в файлы C:\output.htm и C:\output.tab. Все это осталось потому что проект не закончен.
В приложении обычно этого не требуется и отключение указанных особенностей ускорит работу парсера в несколько раз.
Дисклаймер.
По функциональным возможностям парсер конечно уступает MSHTML, и значительно.
С другой стороны, несмотря на то, что он почти не оптимизировался, он работает на два порядка быстрее парсера от Microsoft. Лично для меня это вполне достаточное удобство. Возможно, что и для других тоже.
[EDIT 2007-12-10]
Добавлена альтернативная версия парсера.
Добавлены методы:
- Код: Выделить всё
Public Function GetChildren(lTags() As TagsType, PIndex As Long) As TagsType()
Public Function GetElementByID(lTags() As TagsType, ByVal ID As String) As TagsType
Public Function GetElementsByName(lTags() As TagsType, ByVal Name As String, Optional ByVal PIndex As Long = 1) As TagsType()
Public Function GetElementsByTagName(lTags() As TagsType, ByVal TagName As String, Optional ByVal PIndex As Long = 1) As TagsType()
Public Function GetAttribute(ByVal lTag As TagsType, ByVal Param As String) As Variant
Автор: Antonariy