Я пытался использовать XMLStreamReader
в сочетании с StreamFilter
для частичного чтения из файла XML. Основной метод для этого выглядит следующим образом:
public ScheduleList getScheduleListFromXMLFile(File scheduleListFile, ScheduleTimeRange scheduleTimeRange) {
ScheduleList scheduleList = null;
try {
JAXBContext context = JAXBContext.newInstance(this.getJAXBContextClasses());
Unmarshaller unMarsh = context.createUnmarshaller();
InputStream inputStream = new FileInputStream(scheduleListFile);
XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(inputStream);
// --- Check if a system state filter is to be applied ------------
if (scheduleTimeRange!=null && scheduleTimeRange.isValidTimeRange()==true) {
// --- Add a filter to the XMLStreamReader --------------------
xmlStreamReader = xmlInputFactory.createFilteredReader(xmlStreamReader, new ScheduleList_XMLStreamFilter(scheduleTimeRange));
}
JAXBElement<ScheduleList> jaxbElement = (JAXBElement<ScheduleList>) unMarsh.unmarshal(xmlStreamReader);
xmlStreamReader.close();
inputStream.close();
if (jaxbElement!=null) {
// --- Check if the loaded object is of the required type -----
Object loadedObject = jaxbElement.getValue();
if (loadedObject instanceof ScheduleList) {
scheduleList = (ScheduleList) loadedObject;
} else {
JOptionPane.showMessageDialog(this.getOwnerFrame(), getWarningString(), "Wrong object type", JOptionPane.ERROR_MESSAGE);
}
}
} catch (JAXBException e) {
if (e.getCause() instanceof InstantiationException) {
// --- Try to load based on the previous version ---
scheduleList = EomModelUpdater.getScheduleListFromXMLFile(scheduleListFile);
} else {
e.printStackTrace();
}
} catch (IOException | XMLStreamException ex) {
ex.printStackTrace();
} finally {
convertToTreeScheduleList(scheduleList);
}
return scheduleList;
}
В случае, если 'scheduleTimeRange' имеет значение null, фильтр не будет применен, и операция демаршалинга будет работать нормально. В случае применения фильтра операция не возвращается из метода / строки
JAXBElement<ScheduleList> jaxbElement = (JAXBElement<ScheduleList>) unMarsh.unmarshal(xmlStreamReader);
, даже примененный фильтр сообщает мне, что конец документа достигнут. Метод accept (XMLStreamReader reader) нашего фильтра, который реализует StreamFilter, выглядит следующим образом:
public boolean accept(XMLStreamReader reader) {
if (reader.isStartElement()==true) {
// --- Starting elements --------------------
if (reader.getLocalName().equals("TechnicalSystemStateList")==true) {
// --- Set default accept ---------------
this.acceptSystemState = true;
} else if (reader.getLocalName().equals("GlobalTime")==true) {
// --- Check if TSSE can be accepted ----
try {
String globalTimeText = reader.getElementText();
Long globalTime = this.parseLong(globalTimeText);
if (globalTime!=null) {
this.acceptSystemState = this.scheduleTimeRange.isWithinTimeRange(globalTime);
}
} catch (XMLStreamException xmlStreamEx) {
xmlStreamEx.printStackTrace();
}
}
} else if (reader.isEndElement()==true) {
// --- Ending elements ----------------------
if (reader.getLocalName().equals("TechnicalSystemStateList")) {
return this.acceptSystemState;
}
}
try {
if (reader.hasNext()==false) {
System.out.println("Found end of document");
}
} catch (XMLStreamException e) {
e.printStackTrace();
}
return true;
}
Я понятия не имею, что здесь не так, и был бы очень рад получить подсказку. В настоящее время мы работаем с Java 8 (jdk1.8.0_191).