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

Как читать XML-файл на Java (анализатор Stax)

Потоковый API для примеров XML (STAX) для чтения или анализа XML-документа, чтения XML-элементов, атрибутов, значений, CDATA и т. Д. Примеры API курсора StAX и API итератора.

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

В этом руководстве показано, как использовать Streaming API для XML (STAX) синтаксический анализатор для чтения или анализа XML-документа.

Содержание

  • 1. Что такое StAX
    • 1.1 Разница между саксофоном и стаксом?
  • 2. API курсора StAX и API итератора
    • 2.1 API курсора StAX
    • 2.2 API итератора StAX
    • 2.3 какой из них? API-интерфейсы курсора или итератора?
  • 3. XML-файл
  • 4. API курсора StAX для чтения XML-файла
  • 5. API итератора StAX для чтения XML-файла
  • 6. Конвертировать XML в объекты Java?
  • 7. Скачать Исходный Код
  • 8. Рекомендации

Примечание |/P.S API потоковой передачи для XML (STAX) API доступен с Java 1.6, встроенной библиотеки XML JDK.

P.S Все приведенные ниже примеры протестированы с Java 11.

1. Что такое StAX

StAX расшифровывается как Потоковый API для XML (STAX) , pull API для работы с XML-документом.

Существует две модели программирования для работы с XML-документом: потоковая передача и объектная модель документа (DOM). Для моделей DOM мы можем использовать анализатор DOM ; Для потоковой модели мы можем использовать синтаксический анализатор SAX или синтаксический анализатор Sax.

1.1 Разница между саксофоном и стаксом?

Простой API для XML (SAX) является push API ; этот синтаксический анализатор SAX непрерывно отправляет (push) XML-данные клиенту. В SAX клиент не может контролировать, когда получать XML-данные.

Например, мы регистрируем обычай Обработчик по умолчанию реализация для обработки XML-данных, отправляемых анализатором SAX. Прочитайте полный пример САКСОФОНА .

  // SAX
  SAXParser saxParser = factory.newSAXParser();

  // DefaultHandler implementation
  PrintAllHandlerSax handler = new PrintAllHandlerSax();

  saxParser.parse(FILENAME, handler);

Потоковый API для XML (STAX) является pull API ; клиент вызывает методы в библиотеке синтаксического анализа StAX, чтобы получить (извлечь) XML-данные по одному вручную. InStAX, клиент, контролирующий, когда получать (извлекать) XML-данные.

  // StAX Iterator API examples
  // next event
  XMLEvent event = xmlEventReader.nextEvent();

  // moves to next event
  event = xmlEventReader.nextEvent();

  // moves to next event
  event = xmlEventReader.nextEvent();

Дальнейшее Чтение

2. API курсора StAX и API итератора

StAX содержит два набора API: API курсора и API итератора.

2.1 API курсора StAX

API курсора StAX содержит два основных интерфейса Средство чтения XMLStreamReader и XMLStreamWriter . XMLStreamReader.geteventtype() вернет значение int и нам нужно сопоставить тип события вручную.

  // StAX Cursor API
  XMLStreamReader reader = xmlInputFactory.createXMLStreamReader(
      new FileInputStream(path.toFile()));

  // this is int! we need to map the eventType manually
  int eventType = reader.getEventType();

  while (reader.hasNext()) {

      eventType = reader.next();

      if (eventType == XMLEvent.START_ELEMENT) {
      }
      //...
  }

2.2 API итератора StAX

API итератора Stax содержит два основных интерфейса XMLEventReader и XMLEventWriter , и мы работаем с событием XML .

  // StAX Iterator API
  XMLEventReader reader = xmlInputFactory.createXMLEventReader(
      new FileInputStream(path.toFile()));

  // event iterator
  while (reader.hasNext()) {

      XMLEvent event = reader.nextEvent();

      if (event.isStartElement()) {
      }
      //...
  }

2.3 какой из них? API-интерфейсы курсора или итератора?

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

Дальнейшее Чтение

3. XML-файл

Ниже приведен XML-документ, позже мы используем анализатор StAX для чтения XML-данных и их распечатки.



    
        mkyong
        support
        5000
        
        
    
    
        yflow
        admin
        8000
        
    

4. API курсора StAX для чтения XML-файла

В приведенном ниже примере используется API курсора StAX для чтения или анализа вышеуказанного XML-файла, чтобы получить XML-элементы, атрибуты, CDATA и т.д.

package com.mkyong.xml.stax;

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.events.XMLEvent;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.nio.file.Path;
import java.nio.file.Paths;

public class ReadXmlStAXCursorParser {

    private static final String FILENAME = "src/main/resources/staff.xml";

    public static void main(String[] args) {

        try {

            printXmlByXmlCursorReader(Paths.get(FILENAME));

        } catch (FileNotFoundException | XMLStreamException e) {
            e.printStackTrace();
        }

    }

    private static void printXmlByXmlCursorReader(Path path)
            throws FileNotFoundException, XMLStreamException {

        XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
        XMLStreamReader reader = xmlInputFactory.createXMLStreamReader(
                new FileInputStream(path.toFile()));

        int eventType = reader.getEventType();
        System.out.println(eventType);   // 7, START_DOCUMENT
        System.out.println(reader);      // xerces

        while (reader.hasNext()) {

            eventType = reader.next();

            if (eventType == XMLEvent.START_ELEMENT) {

                switch (reader.getName().getLocalPart()) {

                    case "staff":
                        String id = reader.getAttributeValue(null, "id");
                        System.out.printf("Staff id : %s%n", id);
                        break;

                    case "name":
                        eventType = reader.next();
                        if (eventType == XMLEvent.CHARACTERS) {
                            System.out.printf("Name : %s%n", reader.getText());
                        }
                        break;

                    case "role":
                        eventType = reader.next();
                        if (eventType == XMLEvent.CHARACTERS) {
                            System.out.printf("Role : %s%n", reader.getText());
                        }
                        break;

                    case "salary":
                        String currency = reader.getAttributeValue(null, "currency");
                        eventType = reader.next();
                        if (eventType == XMLEvent.CHARACTERS) {
                            String salary = reader.getText();
                            System.out.printf("Salary [Currency] : %,.2f [%s]%n",
                              Float.parseFloat(salary), currency);
                        }
                        break;

                    case "bio":
                        eventType = reader.next();
                        if (eventType == XMLEvent.CHARACTERS) {
                            System.out.printf("Bio : %s%n", reader.getText());
                        }
                        break;
                }

            }

            if (eventType == XMLEvent.END_ELEMENT) {
                // if 
                if (reader.getName().getLocalPart().equals("staff")) {
                    System.out.printf("%n%s%n%n", "---");
                }
            }

        }

    }

}

Выход

7
com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl@18be83e4

Staff id : 1001
Name : mkyong
Role : support
Salary [Currency] : 5,000.00 [USD]
Bio : HTML tag testing

---

Staff id : 1002
Name : yflow
Role : admin
Salary [Currency] : 8,000.00 [EUR]
Bio : a & b

---

Ниже приведен помощник по коду для типа события API курсора и его внутренний

5. API итератора StAX для чтения XML-файла

В приведенном ниже примере используется API итератора StAX для чтения или анализа вышеуказанного XML-файла, чтобы получить XML-элементы, атрибуты, CDATA и т.д.

package com.mkyong.xml.stax;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.nio.file.Path;
import java.nio.file.Paths;

public class ReadXmlStAXEventParser {

    private static final String FILENAME = "src/main/resources/staff.xml";

    public static void main(String[] args) {

        try {

            printXmlByXmlEventReader(Paths.get(FILENAME));

        } catch (FileNotFoundException | XMLStreamException e) {
            e.printStackTrace();
        }

    }

    private static void printXmlByXmlEventReader(Path path)
            throws FileNotFoundException, XMLStreamException {

        XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
        XMLEventReader reader = xmlInputFactory.createXMLEventReader(
                new FileInputStream(path.toFile()));

        // event iterator
        while (reader.hasNext()) {

            XMLEvent event = reader.nextEvent();

            if (event.isStartElement()) {

                StartElement element = event.asStartElement();

                switch (element.getName().getLocalPart()) {
                    // if 
                    case "staff":
                        // id='1001'
                        Attribute id = element.getAttributeByName(new QName("id"));
                        System.out.printf("Staff id : %s%n", id.getValue());
                        break;
                    case "name":
                        // throws StartElementEvent cannot be cast to class javax.xml.stream.events.Characters
                        // element.asCharacters().getData()

                        // this is still '' tag, need move to next event for the character data
                        event = reader.nextEvent();
                        if (event.isCharacters()) {
                            System.out.printf("Name : %s%n", event.asCharacters().getData());
                        }
                        break;
                    case "role":
                        event = reader.nextEvent();
                        if (event.isCharacters()) {
                            System.out.printf("Role : %s%n", event.asCharacters().getData());
                        }
                        break;
                    case "salary":
                        // currency='USD'
                        Attribute currency = element.getAttributeByName(new QName("currency"));
                        event = reader.nextEvent();
                        if (event.isCharacters()) {
                            String salary = event.asCharacters().getData();
                            System.out.printf("Salary [Currency] : %,.2f [%s]%n",
                              Float.parseFloat(salary), currency);
                        }
                        break;
                    case "bio":
                        event = reader.nextEvent();
                        if (event.isCharacters()) {
                            // CDATA, no problem.
                            System.out.printf("Bio : %s%n", event.asCharacters().getData());
                        }
                        break;
                }
            }

            if (event.isEndElement()) {
                EndElement endElement = event.asEndElement();
                // if 
                if (endElement.getName().getLocalPart().equals("staff")) {
                    System.out.printf("%n%s%n%n", "---");
                }
            }

        }

    }

}

Выход

Staff id : 1001
Name : mkyong
Role : support
Salary [Currency] : 5,000.00 [currency='USD']
Bio : HTML tag testing

---

Staff id : 1002
Name : yflow
Role : admin
Salary [Currency] : 8,000.00 [currency='EUR']
Bio : a & b

---

6. Конвертировать XML в объекты Java?

Да, мы можем использовать API StAX для преобразования XML в объекты Java. Для приведенного выше примера мы уже можем получить XML-данные, создать POJO, например Staff.java и установите значение вручную.

Привязка Jakarta XML (JAXB) – это рекомендуемая библиотека для преобразования XML в/из объектов Java.

7. Скачать Исходный Код

$клон git $клон git

$компакт-диск java-xml

$cd src/основной/java/com/mkyong/xml/stax$cd src/основной/java/com/mkyong/xml/stax/

8. Рекомендации

Оригинал: “https://mkyong.com/java/how-to-read-xml-file-in-java-stax-parser/”