Саморобний парсер XML на Perl

Якщо ви збираєтеся зайнятися розбором HTML або XML, то клас Perl, який ми розробимо в цій статті, може допомогти вам у цій справі.

Не вантажитиму тут про те, навіщо треба грабувати і парсити. Зупинимося на тому, що ми маємо текст, який дуже схожий на XML. І нам треба його швидко та грамотно розпарити.

Постановка задачі

Написати клас, призначений для виконання типових завдань, що постають при розборі xml-подібних текстів.

Чому я говорю xml-подібних? Ну, якщо ви хоч раз пробували парсити текст html-сторінки за допомогою методів DOM, то ви, напевно, упиралися в те, що далеко не кожна html-сторінка — це правильний DOM-документ. Банальний приклад – незакриті теги

Тому потрібно дати можливість передавати потрібний шматок тексту в якості скаляра, в якому будуть шукатися потрібні шматки, з огляду на те, що це все-таки має бути схоже на xml. Тому називаю цей клас LlXMLParser (Look like XML Parser).

Майбутній клас має вміти:

  • збирати всі теги, із заданим ім'ям
  • збирати вміст усіх тегів, із заданим ім'ям
  • збирати значення атрибуту, із заданим ім'ям
  • збирати всі атрибути тега, із заданим ім'ям

Класи в "Perl

Реалізація

Конструктор

Простий конструктор. Повертає посилання, "благословенне" у пакет.

Режим дебагу

Щоб простіше було налагоджувати роботу класу, та й використовувати його пізніше, напишемо метод, який включатиме та вимикатиме режим дебагу.

Режим дебагу полягатиме в тому, щоб повертати не просто значення, а оптимізовані для виведення на екран та налагодження. Для цього нам буде потрібний метод, що перетворює звичайний шматок xml в xml, приготований для виведення наекран.

Функція приймає посилання скаляр і модифікує його.

Збір тегів

Цей метод приймає текст для парсингу та ім'я тега. Потім він шукає в тексті заданий тег. Передбачається, що це тег-контейнер. Якщо це одиночний тег, його атрибути будемо отримувати по-іншому.

Отримання всіх атрибутів тега

Якщо нас цікавить, які атрибути є у тега, то можемо використовувати метод tag_atribs.

Отримаємо посилання на всі атрибути тегів із заданим ім'ям.

Збір вмісту тега

Допустимо, хочемо отримати вміст усіх абзаців. Причому без самих кодів абзаців. Можна скористатися методом tag_contents.

Збір значень конкретного атрибуту

Допустимо, хочемо зібрати всі посилання на картинки зі сторінки. Нам знадобляться значення атрибуту src. Ось спосіб, який дозволить швидко зробити те, що ми задумали.

Власне, отримаємо посилання масив значень нашого атрибута.

Ну і на закусочку можна оснастити наш клас простим методом, який вважатиме, скільки разів у тексті з'являється заданий рядок або регулярне вираження.

Висновок

Звичайно, цей клас є примітивним. Наприклад, він не вміє працювати із вкладеними тегами. Скажімо, конструкцію із вкладених одна в одну таблиць він інтерпретує неправильно. Зате він є простим та зручним інструментом, який вирішує типові завдання захоплення при розборі XML-подібних текстів.

По суті це навіть не клас, а бібліотека. Адже нам навряд чи знадобиться більше одного об'єкта цього класу через те, що ми не зашиваємо текст в об'єкт, а щоразу передаємо шматочок при викликі методів. ОВП тут потрібне лише для того, щоб уникнути конфліктів імен. Крім того, це покращує переносимість бібліотеки.

Можливо згодом, додамметоди для обрізки та вирізки чогось. Так само було б непогано бачити тут методи для пошуку та заміни.

Бувають ще завдання очищення коду. Наприклад, типове завдання - видалення всіх атрибутів (крім важливих типу src) у всіх тегах.

Думав так само, про рекурсивний пошук вкладених тегів, але вирішив, що це не має сенсу, бо вихідний текст лише схожий на xml.

А якщо ви хочете парсити XML або сайти професійно – можете звернутися до мене і я вам у цьому допоможу. Можливо навіть безкоштовно;)