在Spring Batch中,我编写了自己的stax事件项阅读器实现,其操作比前面提到的更具体.基本上,我只是将元素填充到地图中,然后将它们传递给ItemProcessor.从那里,您可以自由地将它转换为“GatheredElement”中的单个对象(请参阅CompositeItemProcessor).抱歉从StaxEventItemReader中获得一点复制/粘贴,但我不认为这是可以避免的.
从这里开始,你可以自由地使用你想要的任何OXM编组器,我也碰巧使用JAXB.
public class ElementGatheringStaxEventItemReader extends StaxEventItemReader {
private Map gatheredElements;
private Set elementsToGather;
...
@Override
protected boolean moveCursorToNextFragment(XMLEventReader reader) throws NonTransientResourceException {
try {
while (true) {
while (reader.peek() != null && !reader.peek().isStartElement()) {
reader.nextEvent();
}
if (reader.peek() == null) {
return false;
}
QName startElementName = ((StartElement) reader.peek()).getName();
if(elementsToGather.contains(startElementName.getLocalPart())) {
reader.nextEvent(); // move past the actual start element
XMLEvent dataEvent = reader.nextEvent();
gatheredElements.put(startElementName.getLocalPart(), dataEvent.asCharacters().getData());
continue;
}
if (startElementName.getLocalPart().equals(fragmentRootElementName)) {
if (fragmentRootElementNameSpace == null || startElementName.getNamespaceURI().equals(fragmentRootElementNameSpace)) {
return true;
}
}
reader.nextEvent();
}
} catch (XMLStreamException e) {
throw new NonTransientResourceException("Error while reading from event reader", e);
}
}
@SuppressWarnings("unchecked")
@Override
protected T doRead() throws Exception {
T item = super.doRead();
if(null == item)
return null;
T result = (T) new GatheredElementItem(item, new HashedMap(gatheredElements));
if(log.isDebugEnabled())
log.debug("Read GatheredElementItem: " + result);
return result;
}
收集的元素类非常基本:
public class GatheredElementItem {
private final T item;
private final Map gatheredElements;
...
}