Results 1 to 10 of 16

Thread: Reading mutilple element types with StaxEventItemReader

Hybrid View

  1. #1
    Join Date
    Apr 2010
    Location
    Brazil
    Posts
    12

    Exclamation 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

  2. #2
    Join Date
    Dec 2005
    Location
    Lyon, France
    Posts
    311

    Default

    You need to configure your StaxEventItemReader and provide it with an Spring OXM Unmarshaller. The latter will convert XML fragments into domain objects. This is explained here. Note you can use any marshalling library supported by Spring OXM (XStream, JAXB2, etc.).

  3. #3
    Join Date
    Apr 2010
    Location
    Brazil
    Posts
    12

    Default

    Thank you for reply!

    I undestand you, but the configuration allows only one fragmentRootElementName. Because of that, i can't map other element type at the same reader.

    I have some Spring Batch samples using StaxEventItemReader, but in everyone, the author didn't use multiple input type.

  4. #4
    Join Date
    May 2010
    Posts
    1

    Default 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");
      }
    }

  5. #5
    Join Date
    Apr 2010
    Location
    Brazil
    Posts
    12

    Default

    Okay! Thank you very much!

    I'm going to implement some tests!!!

  6. #6
    Join Date
    Feb 2008
    Location
    Belgium
    Posts
    23

    Default

    Pay attention that the implementation of MultiFragmentStaxEventItemReader does not support restart. jumpToItem is not overridden and the implementation provided by StaxEventItemReader is based on the first fragmentRootElementName.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •