Какие вы знаете методы чтения XML? Опишите сильные и слабые стороны каждого метода.
В Java существуют три основных метода чтения XML-документов: DOM (объектный), SAX (событийный) и StAX (потоковый). Каждый из них предлагает разный баланс между удобством использования, потреблением памяти и скоростью работы.
DOM (Document Object Model)
DOM-парсер считывает весь XML-документ и воссоздает его в памяти в виде дерева объектов (узлов). Каждый узел может иметь дочерние узлы, формируя иерархическую структуру, по которой можно перемещаться в любом направлении.
SAX (Simple API for XML)
SAX-парсер читает документ последовательно и генерирует события (открытие тега, закрытие тега, текст, атрибут), вызывая зарегистрированные обработчики. Документ в памяти не сохраняется — обработка идет «на лету».
StAX (Stream API for XML)
StAX — потоковый парсер, работающий по принципу pull-модели: приложение само запрашивает следующий элемент, а не ожидает обратного вызова, как в SAX. Предоставляет два API: низкоуровневый cursor API и высокоуровневый event iterator API.
Сравнение методов
| Критерий | DOM | SAX | StAX |
|---|---|---|---|
| Модель | Дерево в памяти | Push (события → callback) | Pull (приложение запрашивает) |
| Потребление памяти | Высокое (весь документ) | Низкое | Низкое |
| Скорость | Низкая | Высокая | Высокая |
| Навигация | Произвольная (любой узел) | Только вперед | Только вперед |
| Сложность кода | Простой | Сложный (state machine) | Умеренный |
| Чтение | Да | Да | Да |
| Запись | Да | Нет | Нет |
| Перекрестные ссылки | Легко (два прохода) | Сложно (ручное хранение) | Сложно |
| Обработка ошибок | Полуструктура уничтожается автоматически | Ручная очистка | Ручная очистка |
Пример чтения XML через DOM
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new File("books.xml"));
NodeList books = document.getElementsByTagName("book");
for (int i = 0; i < books.getLength(); i++) {
Element book = (Element) books.item(i);
String title = book.getElementsByTagName("title")
.item(0).getTextContent();
System.out.println("Title: " + title);
}
Пример чтения XML через SAX
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
parser.parse(new File("books.xml"), new DefaultHandler() {
boolean inTitle = false;
@Override
public void startElement(String uri, String localName,
String qName, Attributes attrs) {
if ("title".equals(qName)) inTitle = true;
}
@Override
public void characters(char[] ch, int start, int length) {
if (inTitle) {
System.out.println("Title: " + new String(ch, start, length));
inTitle = false;
}
}
});
Пример чтения XML через StAX
XMLInputFactory factory = XMLInputFactory.newInstance();
XMLStreamReader reader = factory.createXMLStreamReader(
new FileInputStream("books.xml"));
while (reader.hasNext()) {
int event = reader.next();
if (event == XMLStreamConstants.START_ELEMENT
&& "title".equals(reader.getLocalName())) {
System.out.println("Title: " + reader.getElementText());
}
}
reader.close();
На собеседовании: интервьюер ждет сравнительную таблицу или четкое разграничение по памяти/скорости/удобству. Ключевое отличие SAX от StAX: SAX — push-модель (парсер вызывает ваш код), StAX — pull-модель (ваш код управляет парсером). Частая ошибка — забыть про StAX и сравнивать только DOM и SAX.