package com.example.staxread; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; public class BooksReader { public List<Book> readFromXML(InputStream is) throws XMLStreamException { XMLInputFactory inputFactory = XMLInputFactory.newInstance(); XMLStreamReader reader = null; try { reader = inputFactory.createXMLStreamReader(is); return readDocument(reader); } finally { if (reader != null) { reader.close(); } } } private List<Book> readDocument(XMLStreamReader reader) throws XMLStreamException { while (reader.hasNext()) { int eventType = reader.next(); switch (eventType) { case XMLStreamReader.START_ELEMENT: String elementName = reader.getLocalName(); if (elementName.equals("books")) return readBooks(reader); break; case XMLStreamReader.END_ELEMENT: break; } } throw new XMLStreamException("Premature end of file"); } private List<Book> readBooks(XMLStreamReader reader) throws XMLStreamException { List<Book> books = new ArrayList<>(); while (reader.hasNext()) { int eventType = reader.next(); switch (eventType) { case XMLStreamReader.START_ELEMENT: String elementName = reader.getLocalName(); if (elementName.equals("book")) books.add(readBook(reader)); break; case XMLStreamReader.END_ELEMENT: return books; } } throw new XMLStreamException("Premature end of file"); } private Book readBook(XMLStreamReader reader) throws XMLStreamException { Book book = new Book("", "", null, "", 0); book.setLanguage(reader.getAttributeValue(null, "language")); while (reader.hasNext()) { int eventType = reader.next(); switch (eventType) { case XMLStreamReader.START_ELEMENT: String elementName = reader.getLocalName(); if (elementName.equals("authors")) book.setAuthors(readAuthors(reader)); else if (elementName.equals("title")) book.setTitle(readCharacters(reader)); else if (elementName.equals("category")) book.setCategory(readCategory(reader)); else if (elementName.equals("year")) book.setYear(readInt(reader)); break; case XMLStreamReader.END_ELEMENT: return book; } } throw new XMLStreamException("Premature end of file"); } private List<String> readAuthors(XMLStreamReader reader) throws XMLStreamException { List<String> authors = new ArrayList<>(); while (reader.hasNext()) { int eventType = reader.next(); switch (eventType) { case XMLStreamReader.START_ELEMENT: String elementName = reader.getLocalName(); if (elementName.equals("author")) authors.add(readCharacters(reader)); break; case XMLStreamReader.END_ELEMENT: return authors; } } throw new XMLStreamException("Premature end of file"); } private String readCharacters(XMLStreamReader reader) throws XMLStreamException { StringBuilder result = new StringBuilder(); while (reader.hasNext()) { int eventType = reader.next(); switch (eventType) { case XMLStreamReader.CHARACTERS: case XMLStreamReader.CDATA: result.append(reader.getText()); break; case XMLStreamReader.END_ELEMENT: return result.toString(); } } throw new XMLStreamException("Premature end of file"); } private Category readCategory(XMLStreamReader reader) throws XMLStreamException { String characters = readCharacters(reader); try { return Category.valueOf(characters); } catch(IllegalArgumentException e) { throw new XMLStreamException("Invalid category " + characters); } } private int readInt(XMLStreamReader reader) throws XMLStreamException { String characters = readCharacters(reader); try { return Integer.valueOf(characters); } catch (NumberFormatException e) { throw new XMLStreamException("Invalid integer " + characters); } } }