Рубрики
Без рубрики

Синтаксический анализ XML – файла С помощью SAX Parser

Узнайте, как анализировать XML-файл на Java с помощью SAX Parser.

Автор оригинала: baeldung.

1. Обзор

SAX, также известный как Простой API для XML , используется для анализа XML-документов.

В этом уроке мы узнаем, что такое саксофон и почему, когда и как его следует использовать.

2. SAX: простой API для XML

SAX-это API, используемый для анализа XML-документов. Он основан на событиях , генерируемых при чтении документа. Методы обратного вызова получают эти события. Пользовательский обработчик содержит эти методы обратного вызова.

API эффективен, потому что он отбрасывает события сразу после того, как обратные вызовы получили их. Таким образом, SAX имеет эффективное управление памятью , в отличие, например, от DOM.

3. САКСОФОН против ДОМА

DOM означает Объектную модель документа. Синтаксический анализатор DOM не полагается на события . Более того, он загружает весь XML-документ в память для его анализа. SAX более эффективен в использовании памяти, чем DOM.

У ДОМА тоже есть свои преимущества. Например, DOM поддерживает XPath. Это также упрощает работу со всем деревом документов сразу, так как документ загружается в память .

4. САКСОФОН против стакса

StAX появился позже, чем SAX и DOM. Он расшифровывается как Streaming API для XML .

Основное различие с SAX заключается в том, что StAX использует механизм вытягивания вместо механизма выталкивания SAX (с использованием обратных вызовов).
Это означает, что контроль предоставляется клиенту, чтобы решить, когда события должны быть извлечены. Поэтому нет необходимости вытаскивать весь документ целиком, если требуется только его часть.

Он предоставляет простой API для работы с XML с эффективным способом анализа памяти.

В отличие от SAX, он не обеспечивает проверку схемы в качестве одной из своих функций.

5. Анализ XML-файла С помощью пользовательского обработчика

Теперь давайте используем следующий XML, представляющий веб-сайт Baeldung и его статьи:


    
        
Parsing an XML File Using SAX Parser SAX Parser's Lorem ipsum...
Parsing an XML File Using DOM Parser DOM Parser's Lorem ipsum...
Parsing an XML File Using StAX Parser StAX's Lorem ipsum...

Мы начнем с создания POJOS для нашего корневого элемента Baeldung и его дочерних элементов:

public class Baeldung {
    private List articleList;
    // usual getters and setters
}
public class BaeldungArticle {
    private String title;
    private String content;
    // usual getters and setters
}

Мы продолжим, создав BaeldungHandler . Этот класс будет реализовывать методы обратного вызова, необходимые для захвата событий.

Мы переопределим четыре метода из суперкласса Обработчика по умолчанию, каждый из которых характеризует событие:

    • символы(char[], int, int) получает символы с границами. Мы преобразуем их в Строку и сохраним ее в переменной BaeldungHandler
    • startDocument() вызывается при начале синтаксического анализа – мы будем использовать его для создания нашего экземпляра Baeldung
    • startElement() вызывается, когда начинается синтаксический анализ элемента – мы будем использовать его для построения либо List , либо BaeldungArticle экземпляров – QName помогает нам провести различие между обоими типами
    • endElement() вызывается, когда синтаксический анализ заканчивается для элемента – это когда мы назначим содержимое тегов соответствующим переменным

Теперь, когда все обратные вызовы определены, мы можем написать обработчик Baeldung класс:

public class BaeldungHandler extends DefaultHandler {
    private static final String ARTICLES = "articles";
    private static final String ARTICLE = "article";
    private static final String TITLE = "title";
    private static final String CONTENT = "content";

    private Baeldung website;
    private StringBuilder elementValue;

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        if (elementValue == null) {
            elementValue = new StringBuilder();
        } else {
            elementValue.append(ch, start, length);
        }
    }

    @Override
    public void startDocument() throws SAXException {
        website = new Baeldung();
    }

    @Override
    public void startElement(String uri, String lName, String qName, Attributes attr) throws SAXException {
        switch (qName) {
            case ARTICLES:
                website.articleList = new ArrayList<>();
                break;
            case ARTICLE:
                website.articleList.add(new BaeldungArticle());
                break;
            case TITLE:
                elementValue = new StringBuilder();
                break;
            case CONTENT:
                elementValue = new StringBuilder();
                break;
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        switch (qName) {
            case TITLE:
                latestArticle().setTitle(elementValue.toString());
                break;
            case CONTENT:
                latestArticle().setContent(elementValue.toString());
                break;
        }
    }

    private BaeldungArticle latestArticle() {
        List articleList = website.articleList;
        int latestArticleIndex = articleList.size() - 1;
        return articleList.get(latestArticleIndex);
    }

    public Baeldung getWebsite() {
        return website;
    }
}

Строковые константы также были добавлены для повышения удобочитаемости. Также удобен способ извлечения последней обнаруженной статьи. Наконец, нам нужен геттер для объекта Baeldung .

Обратите внимание, что вышесказанное не является потокобезопасным, так как мы удерживаем состояние между вызовами метода.

6. Тестирование парсера

Чтобы проверить синтаксический анализатор, мы создадим экземпляр SaxFactory , SAXParser , а также BaeldungHandler :

SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
SaxParserMain.BaeldungHandler baeldungHandler = new SaxParserMain.BaeldungHandler();

После этого мы проанализируем XML-файл и утвердим, что объект содержит все ожидаемые элементы, проанализированные:

saxParser.parse("src/test/resources/sax/baeldung.xml", baeldungHandler);

SaxParserMain.Baeldung result = baeldungHandler.getWebsite();

assertNotNull(result);
List articles = result.getArticleList();

assertNotNull(articles);
assertEquals(3, articles.size());

SaxParserMain.BaeldungArticle articleOne = articles.get(0);
assertEquals("Parsing an XML File Using SAX Parser", articleOne.getTitle());
assertEquals("SAX Parser's Lorem ipsum...", articleOne.getContent());

SaxParserMain.BaeldungArticle articleTwo = articles.get(1);
assertEquals("Parsing an XML File Using DOM Parser", articleTwo.getTitle());
assertEquals("DOM Parser's Lorem ipsum...", articleTwo.getContent());

SaxParserMain.BaeldungArticle articleThree = articles.get(2);
assertEquals("Parsing an XML File Using StAX Parser", articleThree.getTitle());
assertEquals("StAX Parser's Lorem ipsum...", articleThree.getContent());

Как и ожидалось, файл baeldung был правильно проанализирован и содержит ожидаемые подобъекты.

7. Заключение

Мы только что узнали, как использовать SAX для анализа XML-файлов. Это мощный API, генерирующий небольшой объем памяти в наших приложениях.

Как обычно, код для этой статьи доступен на GitHub .