Gymterview
middle

Какие вы знаете методы чтения 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.