В этой статье мы продолжим изучать различные способы обработки XML файлов и сегодня познакомимся с Java StAX на базе курсора. Ниже представлены краткие теоретические сведения и пример работы. Из прошлой статьи мы узнали, что Java StAX API обеспечивает два способа обработки XML: на базе итератора и на базе курсора. На примере последнего мы сегодня и будем разбираться XML файл.
Как использовать Java StAX Cursor API
Для чтения XML-файла с помощью StAX Parser нужно получить экземпляр класса XMLInputFactory
, с помощью которого получаем объект XMLStreamReader
для чтения XML файла. Далее мы обходим XML файл в while цикле с помощью метода next()
и получаем различные типы событий. Вспомогательный класс XMLStreamConstants
содержит целочисленные константы для определения типа событий.
Ниже представлен XML-файл, который мы будем разбирать с помощью Java StAX Cursor API:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?xml version="1.0" encoding="UTF-8"?> <Students> <Student id="1"> <name>Andrey</name> <age>21</age> <language>Java</language> </Student> <Student id="2"> <name>Viktor</name> <age>20</age> <language>C++</language> </Student> <Student id="2"> <name>Dima</name> <age>22</age> <language>JavaScript</language> </Student> </Students> |
Создадим класс, экземпляры которого будут хранить информацию из XML файла:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
package ua.com.prologistic; public class Student { private String name; private int age; private int id; private String language; @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + ", id=" + id + ", language='" + language + '\'' + '}'; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getLanguage() { return language; } public void setLanguage(String language) { this.language = language; } public int getId() { return id; } public void setId(int id) { this.id = id; } } |
Ниже представлен листинг класса XMLStaxCursorParser
для разбора XML с помощью StAX Cursor:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
package ua.com.prologistic; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.List; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; public class XMLStaxCursorParser { // флаги для событий XML файла private static boolean nameFlag; private static boolean ageFlag; private static boolean languageFlag; public static void main(String[] args) { String fileName = "F:/students.xml"; List<Student> studentsList = parseXMLfile(fileName); // печатаем в консоль информацию по каждому студенту for (Student student : studentsList) { System.out.println( student.toString()); } } // метод парсинга XML файла с помощью Cursor API private static List<Student> parseXMLfile(String fileName) { List<Student> studentsList = new ArrayList<>(); Student student = null; XMLInputFactory factory = XMLInputFactory.newInstance(); try { XMLStreamReader reader = factory.createXMLStreamReader(new FileInputStream(fileName)); // получаем первое событие int event = reader.getEventType(); // обходим весь XML файл while (true) { // проходим по типам событий switch (event) { case XMLStreamConstants.START_ELEMENT: // в зависимости от имени тега отмечаем нужный фалг if (reader.getLocalName().equals("Student")) { student = new Student(); student.setId(Integer.parseInt(reader.getAttributeValue(0))); } else if (reader.getLocalName().equals("name")) { nameFlag = true; } else if (reader.getLocalName().equals("age")) { ageFlag = true; } else if (reader.getLocalName().equals("language")) { languageFlag = true; } break; // сохраняем данные XML-элемента, // флаг которого равен true в объект Student case XMLStreamConstants.CHARACTERS: if (nameFlag) { student.setName(reader.getText()); nameFlag = false; } else if (ageFlag) { student.setAge(Integer.parseInt(reader.getText())); ageFlag = false; } else if (languageFlag) { student.setLanguage(reader.getText()); languageFlag = false; } break; // если цикл дошел до закрывающего элемента узла Student, то сохраняем объект в список case XMLStreamConstants.END_ELEMENT: if (reader.getLocalName().equals("Student")) { studentsList.add(student); } break; } // если больше элементов нет, то заканчиваем обход файла if (!reader.hasNext()) break; // переход к следующему событию event = reader.next(); } } catch (FileNotFoundException | XMLStreamException e) { e.printStackTrace(); } return studentsList; } } |
В результате получим вот такой вывод на консоль:
1 2 3 |
Student{name='Andrey', age=21, id=1, language='Java'} Student{name='Viktor', age=20, id=2, language='C++'} Student{name='Dima', age=22, id=3, language='JavaScript'} |
Следите за обновлениями раздела Обработка XML в Java и подписывайтесь на обновления сайта.