Reading mutilple element types with StaxEventItemReader
Dear Friends,
I need to read multiple types of elements from XML input and bind to objects. I believe that is possible using StaxEventItemReader, but i don't know how.
If it's not possible, please, tell me how can I do that using other ItemReader? Or if necessary, suggestions of custom XMLItemReader implementations.
Thanks from Brazil.
Fabiano
MultiFragmentStaxEventItemReader
I had the same problem and came up with the following solution:
Code:
package x.y.z;
import java.util.List;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.StartElement;
import org.apache.commons.lang.Validate;
import org.springframework.batch.item.xml.StaxEventItemReader;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.dao.DataAccessResourceFailureException;
/**
* An enhanced <code>StaxEventItemReader</code> to handle multiple node element
* names that need to be extracted.
*
* @author mazehnder
*/
public class MultiFragmentStaxEventItemReader<T> extends StaxEventItemReader<T>
implements InitializingBean {
private List<String> fragmentRootElementNames;
public void setFragmentRootElementNames(List<String> fragmentRootElementNames) {
if (fragmentRootElementNames == null || fragmentRootElementNames.isEmpty()) {
throw new IllegalArgumentException("At least one root element name must be provided");
}
// to satisfy super class's afterPropertiesSet
super.setFragmentRootElementName(fragmentRootElementNames.get(0));
this.fragmentRootElementNames = fragmentRootElementNames;
}
@Override
protected boolean moveCursorToNextFragment(XMLEventReader reader) {
try {
while (true) {
while (reader.peek() != null && !reader.peek().isStartElement()) {
reader.nextEvent();
}
if (reader.peek() == null) {
return false;
}
QName startElementName = ((StartElement) reader.peek()).getName();
String elementName = startElementName.getLocalPart();
if (fragmentRootElementNames.contains(elementName)) {
return true;
} else {
reader.nextEvent();
}
}
} catch (XMLStreamException e) {
throw new DataAccessResourceFailureException("Error while reading from event reader", e);
}
}
@Override
public void afterPropertiesSet() throws Exception {
super.afterPropertiesSet();
Validate.notNull(fragmentRootElementNames, "Property fragmentRootElementNames must not be null");
Validate.notEmpty(fragmentRootElementNames, "Property fragmentRootElementNames must not be empty");
}
}
MultiFragmentStaxEventItemReader with restart
hi there,
Is it possible to make MultiFragmentStaxEventItemReader restartable? Make it restartable is a major issue in our project at the moment where we have to read complex xml files.
Hope anyone has a clue.
Thanks in advance!
Wop