Results 1 to 6 of 6

Thread: Using XPATH to Marshall xml

  1. #1

    Default Using XPATH to Marshall xml

    Hey Guys,
    Im a newbie trying to setup spring batch and I have a question about the best way to handle my data import.
    So, currently I need to import some xml data, but my data is deeply nested and I need to only extract two values out of about 50 in each record.

    I see the XMLStreamMarshaller but it doesn't seem to support namespaces very effectively. Is there a way I could use an XPATH query to bind my values to my object?

    thanks guys.
    -matt

  2. #2
    Join Date
    Jun 2005
    Posts
    4,230

    Default

    I'm not really sure where you are getting an XMLStreamMarshaller from (there is an XStreamMarshaller in Spring OXM, I believe - maybe that?). Anyway, you could ask this question in the Web Services forum because that us the home of the OXM framework that we use in Batch. If you don't get anything there you might need to write your own EventReaderDeserializer.

  3. #3

    Default

    Ill give that a try.
    Thanks!

  4. #4

    Default NamespaceBasedEventReaderDeserializer

    So, we tackled the xml issue by implementing our own EventReaderDesierializer.
    It takes a list of namespaces that we are looking for and finds those values and puts them in a map. It's no xpath, but it at least will handle deep structures. Note: The namespaces need to be unique, you will get collisions if you don't.

    Code:
    public class NamespaceBasedEventReaderDeserializer implements EventReaderDeserializer
    {
    	private Log logger = LogFactory.getLog(NamespaceBasedEventReaderDeserializer.class);
    	private List<String> namespaces = new ArrayList<String>();
    
    	public Object deserializeFragment(XMLEventReader eventReader)
    	{
    		Map<String, String> aliases = new HashMap<String, String>();
    		if(namespaces.isEmpty())
    		{
    			logger.warn("We are not looking for any data in our pathBasedEventReader - ");
    			return aliases;
    		}
    		List<String> localPaths = new ArrayList<String>(namespaces);
    
    		while(eventReader.hasNext())
    		{
    			XMLEvent event = (XMLEvent) eventReader.next();
    			for(Iterator<String> iterator = localPaths.iterator(); iterator.hasNext();)
    			{
    				String key = iterator.next();
    				if(StringUtils.contains(event.getLocation().toString(), key)
    						&& event.isStartElement())
    				{
    					XMLEvent found = (XMLEvent) eventReader.next();
    					if(found.getEventType() == XMLStreamConstants.CHARACTERS)
    					{
    						String value = found.toString().trim();
    						aliases.put(key, value);
    						iterator.remove();
    					}
    				}
    			}
    		}
    		return aliases;
    	}
    
    	/**
    	 * @return the namespaces
    	 */
    	public List<String> getNamespaces()
    	{
    		return namespaces;
    	}
    
    	/**
    	 * @param namespaces the namespaces to set
    	 */
    	public void setNamespaces(List<String> namespaces)
    	{
    		this.namespaces = namespaces;
    	}
    
    
    }
    Here is how we call it:
    Code:
    <property name="itemReader">
    	<bean class="org.springframework.batch.item.xml.StaxEventItemReader">
    		<property name="fragmentRootElementName"
    			value="order" />
    		<property name="resource"
    			value="com/bc/batch/mlregister/mldata.xml" />
    		<property name="fragmentDeserializer">
    			<bean
    				class="com.bc.batch.NamespaceBasedEventReaderDeserializer">
    				<property name="namespaces">
    					<list>
    						<value>customerCode</value>
    						<value>email</value>
    					</list>
    				</property>
    			</bean>
    		</property>
    	</bean>
    </property>
    Last edited by MattMacchia; Mar 21st, 2008 at 02:06 PM.

  5. #5
    Join Date
    Dec 2006
    Posts
    1,061

    Default

    Do you mind creating an issue against 1.1 with the code you just posted? That way we can look at it for the enhancements release.

  6. #6

    Default

    No problem.
    Consider it done.

Posting Permissions

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