Reputation: 146
I am new to Stax and XStream. I am trying to unmarshall some common elements from huge XML stream (there might be between 1.5 million and 2.5 million elements to unmarshal)
I have tried to Stax to parse the stream to get to an element of interest and then call xStream to unMarshall the XML up to the EndElement.
XMLStreamReader reader = xmlInputFactory.createXMLStreamReader(fis);
while (reader.hasNext()) {
if (reader.isStartElement() && reader.getLocalName().toLowerCase().equals("person")) {
break;
}
reader.next();
}
StaxDriver sd = new StaxDriver();
AbstractPullReader rd = sd.createStaxReader(reader);
XStream xstream = new XStream(sd);
xstream.registerConverter(new PersonConverter());
Person p = (Person) xstream.unmarshal(rd);
I create a test input
<Persons>
<Person>
<name>A</name>
</Person>
<Person>
<name>B</name>
</Person>
<Person>
<name>C</name>
</Person>
</Persons>
The problem with this, is that first my converter is not called. Second, I get a CannotResolveClassException for the element "name" in Person and XStream doesn't create my Person object. What did I miss in my code?
Upvotes: 0
Views: 550
Reputation: 7286
When you instantiate an AbstractPullReader
it will read the first open-element event from the stream, establishing the "root" element. Because you've already read the first Person
event it will advance to the next one (name
), which it doesn't know how to unmarshal.
You'll have to do two things to make your example work:
First, alias the element name Person
to your java class
xstream.alias("Person", Person.class);
Second, only advance the SAX cursor up to the element before the one you want to read:
while (reader.hasNext()) {
if (reader.isStartElement() && reader.getLocalName().equals("Persons")) {
break;
}
reader.next();
}
Upvotes: 1