“Going back” in a stream implies some kind of memory, so there is no point in sticking to the most memory-efficient tool.
XMLEventReader
can handle this with ease:
public class Main {
public static void main(String args[]) throws Exception {
Unmarshaller aUnmarshaller = JAXBContext.newInstance(A.class).createUnmarshaller();
Unmarshaller bUnmarshaller = JAXBContext.newInstance(B.class).createUnmarshaller();
Unmarshaller cUnmarshaller = JAXBContext.newInstance(C.class).createUnmarshaller();
try (InputStream input = Main.class.getResourceAsStream("InputEPCISEvents.xml")) {
XMLEventReader reader = XMLInputFactory.newInstance().createXMLEventReader(input);
while (reader.hasNext()) {
XMLEvent event = reader.peek();
if (event.isStartElement()) {
switch (event.asStartElement().getName().getLocalPart()) {
case "a" -> System.out.println(aUnmarshaller.unmarshal(reader));
case "b" -> System.out.println(bUnmarshaller.unmarshal(reader));
case "c" -> System.out.println(cUnmarshaller.unmarshal(reader));
}
}
reader.next();
}
}
}
@XmlAccessorType(XmlAccessType.FIELD)
static class ABC {
String name;
String age;
public String toString() {
return getClass().getSimpleName() + "{name="" + name + "", age="" + age + "}";
}
}
@XmlRootElement static class A extends ABC {}
@XmlRootElement static class B extends ABC {}
@XmlRootElement static class C extends ABC {}
}
Output:
C{name="CName', age="CAge}
B{name="BName', age="BAge}
A{name="AName', age="AAge}
B{name="BName', age="BAge}
By the way, your XML needs to be wrapped in a parent element as it contains more than one root element.