Освоюємо sax парсер quick start, dev64
Проте, SAX API вельми важливий і лежить в основі багатьох інших технологій, тому я вирішив вивчити SAX API трохи докладніше. Нижче переклад матеріалів з офіційного сайту. Я знайшов їх дуже цікавими і такими, що заслуговують більш докладного вивчення.
SAX - загальний інтерфейс реалізований для багатьма XML парсер (і штуками, які позиціонують себе як XML парсери), він практично є на стільки ж загальним API для роботи з XML, наскільки JDBC є загальним інтерфейсом, реалізованим для різних реляційних баз даних (і штруковінамі, які позиціонують себе як реляційні бази даних). Якщо ви хочете використовувати SAX, вам будуть потрібні все перераховане нижче:
- Java 1.1 або більш сучасною.
- SAX2-сумісний XML парсер, зазначений у вашому Java classpath. Якщо вам потрібен подібний парсер, дивіться посилання.
- SAX2 дистрибутив, зазначений у вашому Java classpath. (Найімовірніше, ви отримаєте його разом з вашим парсером).
- Більшість Java / XML дистрибутивів включають SAX2 парсер. Більшість Web application серверів використовують його для роботи з XML. Всі дистрибутиви з підтримкою JAXP 1.1 включають підтримку SAX2.
Парсинг XML документа
Почніть створенням класу, який успадковує (extends) DefaultHandler:
Так як це Java - додаток, ми створимо статичний метод main, який використовує метод createXMLReader класу XMLReaderFactory для вибору SAX драйвера динамічно (програмно). Обробка винятків видалена з прикладу для полегшення розуміння. Реальне додаток повинен обробляти виключення:
У разі, якщо ваша Java середовище розробки автоматично Не додає compiled-in default (або не налаштовує META-INF / services / org.xl.sax.driver system resource), вам ймовірно буде потрібно встановити в Java system property оrg.xml.sax. driver значення, яке вказує повний шлях до SAX driver, як в прикладі:
Безліч різних SAX2 драйверів поширені на сьогоднішній день Тому в якості імені класу ви можете використовувати, наприклад:
Optionally validates; Open Source
Інакше, якщо вас не турбує прив'язка вашого застосування до певного SAX драйверу, ви можете використовувати його конструктор безпосередньо. Ми припускаємо, що SAX driver для вашого XML парсеру називається com.example.xml.SAXDriver, однак, в реальності такого класу не існує. Ви повинні знати ім'я справжнього драйвера для вашого парсера, щоб використовувати такий підхід.
Створений об'єкт може бути використаний для парсинга XML-документів, але перш за все, потрібно зареєструвати обробники подій, які парсер може використовувати для передачі інформації. Це робиться за допомогою методів setContentHandler і setErrorHandler інтерфейсу XMLReader. У цьому додатку, ці обробники будуть зазвичай різними об'єктами, але для наведеного простого прикладу, ми поміщаємо ці обробники в Top-level class. Таким чином нам потрібно створити наш клас і зареєструвати його в XMLReader:
Наведений приклад створює екземпляр MySAXApp для отримання XML parsing events і реєструє його в XML reader для отримання regular content подій і error подій (тобто інші види подій, але вони рідко використовуються). Тепер давайте припустимо, що всі аргументи командного рядка - імена файлів і ми будемо намагатися парсити їх по-одному використовуючи метод parse з інтерфейсу XMLReader:
Зауважте, що кожен reader повинен бути представлений InputSource об'єктом, щоб бути «распарсенним». Нижче повний приклад описаного demo класу:
Ви можете відкомпілювати цей код і запустити його (Не забудьте вказати SAX driver клас у властивості org.xml.sax.driver), проте нічого особливого не виникне, якщо тільки ваш документ не містить «поганий» XML, оскільки ви поки не встановили оброблювачів SAX подій для вашого застосування.
Все стає цікавіше коли ви починаєте реалізовувати методи для реакції на XML parsing events (пам'ятаєте ми зареєстрували наш клас для отримання XML parsing events в попередньому розділі). Найбільш важливі події - початок і завершення документа (start and end of the document), початок і завершення елемента (start and end of elements) і символьних даних.
Щоб дізнатися про початок і завершення документа, клієнтську програму реалізує методи startDocument і endDocument.
Обробники подій start / endDocument не мають аргументів. Коли SAX driver знаходить початок документа, він викличе функцію startDocument один раз, коли знайде завершення документа - викличе endDocuemnt (навіть якщо були виявлені помилки).
Наведені приклади друкую повідомлення в стандартний output, але ваше додаток може містити будь-який код для цих обробників, найбільш часто, цей код буде створювати якийсь тип дерева в пам'яті, робити висновок, виробляти збереження в базу даних або отримувати інформацію з XML stream.
SAX driver буде повідомляти про стартових і кінцевих елементах практично також за винятком того, що він буде передавати кілька параметрів в методи startElement і endElement.
Наведені методи будуть друкувати на початку і в кінці кожного елемента. Перед ім'ям елемента (local name) буде друкуватися namespace URI в фігурних дужках. Параметр qName містить ім'я без namespace в форматі XML 1.0, яке ви повинні використовувати для всіх елементів не мають namespace URI. У цьому Quick Introduction, ми не будемо розглядати як обробляються атрибути. Атрибути можуть бути отримані на ім'я або итерацией по ним як ніби вони зберігаються в масиві.
Нарешті, SAX2 передає (reports) звичайні символьні дані через метод characters. Наступний приклад надрукує всі символьні дані на екран. Output буде можливо злегка довше бо він виробляє escaping спеціальних символів (pretty-prints the output by escaping special characters):
Зауважте, що SAX driver може розбивати символьні дані як завгодно, так що ви не можете розраховувати на те, що всі символьні дані прийдуть в одну подію (single characters event).
Приклад SAX2 додатки
Нижче приклад готового додатка (звичайно в цьому додатку обробники подій будуть швидше за все реалізовані в окремому класі, а не в класі програми).
Припустимо обробляється наступний XML документ:
Якщо цей документ названо roses.xml і у вас є SAX2 driver в classpath з ім'ям com.example.xml.SAXDriver (наведений в прикладі на ділі не існує), в можете викликати приклад програми приблизно так:
При запуску, ви отримати output подібний цьому:
Зауважте, що навіть цей короткий документ генерує (по крайней мере) 25 подій: один на старт і завершення кожного з шести елементів (тегів), один на кожен з одинадцяти фрагментів символьних даних і один на старт і завершення документа.
Найбільш ймовірно, вам доведеться працювати з обома типами документів: c документами використовують XML namespace-и і не використовують їх. Документи можуть бути також з різними елементами (частина елементів і атрибутів з namespace, частина немає). У будь-якому випадку переконайтеся, що ваш код перевіряє namespace URI елементів, а не просто розраховує на те, що він завжди є або його завжди немає.