![]() |
|
Модераторы: Aliance, skyboy, MoLeX, ksnk |
![]()
|
|
| MyDarkSide |
|
||||||||||||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 69 Регистрация: 21.3.2008 Репутация: нет Всего: -1 |
Недавно пришлось усердно парсить XHTML через PHP. может мой опыт кому то пригодиться. Для профи скорее всего это не будет откровением, но новичкам кое-чем поможет.
И так первое, если парсить XHTML (или XML) предполагается DOM парсером, убедитесь что перед определением
нет никаких символов в том числе пробелов! иначе это вызовет ошибку и парсер остановиться. Я решаю эту проблему так:
Второе. Очень часто XHTML надо пропарсить так, что бы получить ассоциативный массив, где ключами выступают тэги. Задача осложняется тем, что XHTML может содержать тэги которые просто указывают на форматирование данных, но не на их структуру (<small> <br/> и т.д.). в этом случае массив зассоряется не нужными ключами. Еще хуже если расположение форматирующих тэгов носит не регулярный характер, например
в этом случае после парсинга данные в массиве оказываются на разном уровне вложенности:
Работать с таким массивом потом "одно удовольствие". Кроме того, для парсинга такого XHTML не обойтись без рекурсивного обхода в глубину, что медленно и требует памяти, особенно для структур с глубокими вложениями. Я советую перед тем как скармливать XHTML парсеру (не важно как он выполнен) провести предварительную подготовку данных, так что бы он не много похудели:
В массиве $trash указываем какие тэги надо вырезать, приведенное решение не идеальное, универсальнее использовать регулярки для удаления действительно парных тэгов, но они гораздо медленее. Главное что нужно помнить при таком подходе что в $trash надо указывать тэги которые не содержат в себе аттрибутов (в вашем документе), иначе фильтр сработает не правильно. Если вы используете в парсере метод getElementsByTagName(name) - то вырезать <name> естественно нельзя. Что дает предварительная фильтрация: при правильном указании засоряющих тэгов гораздо снижается размер парсируемого документа -> меньше требуется времени и памяти. Структура документа упрощается и в некоторых случаях можно вообще обойтись без рекурсивного обхода. Если в документе ищется определенная инфа через регулярки - упрощается их шаблон. Вообще предварительной подготовке данных перед парсингом следует уделять внимание, это может очень помочь впоследствии. Третье. Многие знают, но тем не менее периодически многие же наступают на эти грабли: по умолчанию в XML (XHTML естественно тоже) пробел между тэгами воспринимается как текстовый тэг!
внутри тэга span два тэга! #text и #b и если обратиться к свойству nextSibling->nodeValue (DOM PHP5) узла span то оно вернет пробел вместо ожидаемого "текст". Чтобы этого избежать необходимо свойство preserveWhiteSpace экземпляра класса domDocument установить в false
К сожалению, у меня были случае когда этот прием не срабатывал по неизвестной причине. Так что возможно об этом следует позаботиться самому и включить вырезание лишних пробелов в предварительную подготовку данных. |
||||||||||||||
|
|||||||||||||||
| SelenIT |
|
|||
![]() баг форума ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3996 Регистрация: 17.10.2006 Где: Pale Blue Dot Репутация: нет Всего: 401 |
Имхо, для фильтрации и выделения нужного куска X(HT)ML удобнее использовать XSLT, а не регулярки. Тогда и с атрибутами морочиться не надо...
-------------------- Осторожно! Данный юзер и его посты содержат ДГМО! Противопоказано лицам с предрасположенностью к зонеризму! |
|||
|
||||
| MyDarkSide |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 69 Регистрация: 21.3.2008 Репутация: нет Всего: -1 |
SelenIT,
спору нет PHP5 + XML +XSLT - мощнейший инструмент, но как с любым мощным инструментом с ним надо уметь обращаться, а для новичка написать правильный xsl шаблон не совсем просто. А я предложил простое и быстрое решение (как всегда в жертву приноситься универсальность, но тут уж ничего не поделаешь, как всегда, или одно - или другое :( ). Вырезке здесь подвергаются тэги (именно тэги) которые редко используются с какими-либо атрибутами - типа <b>, <u>, <strong> и т.д. в то же время если тэг содержит какой-нибудь аттрибут, то лучше этот тэг не вырезать, в аттрибуте может оказаться очень важная информация. |
|||
|
||||
![]()
|
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | PHP: X технологии | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |