Announcement Announcement Module
Collapse
No announcement yet.
XPathTransformer evaluateAsNodeList Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • XPathTransformer evaluateAsNodeList

    I am using XPathTransformer to transform an XML payload with multiple nodes. If I specify evaluation-type="NODE_LIST_RESULT", I get multiple Nodes in the result, which is great but I want to map the Nodes into a different type. If I inject a NodeMapper, only the first Node in the result is mapped.

    I think this is due to the if/else logic in XPathTransformer.doTransform(Message<?> message) https://fisheye.springsource.org/bro...?hb=true#to100

    I can refactor my configuration to split/aggregate the messages, but it seems like XPathTransformer would benefit from separating the evaluation-type and node-mapper concerns, allowing both if specified. Is it possible to support List<Node> evaluateAsNodeList(Node node) in XPathTransformer?

    I'm new to Spring Integration, so please tell me if I'm doing it wrong. The configuration/code/output example is below.

    context.xml
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans
    	xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:int="http://www.springframework.org/schema/integration"
    	xmlns:int-stream="http://www.springframework.org/schema/integration/stream"
    	xmlns:int-xml="http://www.springframework.org/schema/integration/xml"
    	xsi:schemaLocation="
    		http://www.springframework.org/schema/integration/xml
    		http://www.springframework.org/schema/integration/xml/spring-integration-xml.xsd
    		http://www.springframework.org/schema/integration/stream
    		http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd
    		http://www.springframework.org/schema/beans
    		http://www.springframework.org/schema/beans/spring-beans.xsd
    		http://www.springframework.org/schema/integration
    		http://www.springframework.org/schema/integration/spring-integration.xsd">
    		
    	<int-xml:xpath-transformer input-channel="input" output-channel="stdout" xpath-expression="/foo/bar/@id"
    		evaluation-type="NODE_LIST_RESULT"/>
    
    	<int-xml:xpath-transformer input-channel="input-mapper" output-channel="stdout" xpath-expression="/foo/bar/@id"
    		evaluation-type="NODE_LIST_RESULT" node-mapper="nodeMapper"/>
    	
    	<bean id="nodeMapper" class="fluid.examples.xml.TestNodeMapper"/>
    	
    	<int-stream:stdout-channel-adapter id="stdout" append-newline="true"/>
    	
    </beans>
    fluid.examples.xml.XmlMain.java
    Code:
    public class XmlMain {
    
    	public static void main(String[] args) throws IOException {
    		// load the application context
    		ApplicationContext context = new ClassPathXmlApplicationContext("context.xml", XmlMain.class);
    		
    		// build a message
    		Resource resource = context.getResource("fluid/examples/xml/sample.xml");
    		Message<String> message = MessageBuilder.withPayload(IOUtils.toString(resource.getInputStream())).build();
    		MessageChannel channel = null;
    		
    		// send a message directly to the stdout channel
    		channel= context.getBean("stdout", MessageChannel.class);
    		channel.send(message);
    		
    		// send a message to input
    		channel = context.getBean("input", MessageChannel.class);
    		channel.send(message);
    		
    		// send a message to input mapper
    		channel = context.getBean("input-mapper", MessageChannel.class);
    		channel.send(message);
    	}
    }
    fluid.examples.xml.TestNodeMapper
    Code:
    public class TestNodeMapper implements NodeMapper<String> {
    
    	public String mapNode(Node node, int i) throws DOMException {
    		Attr attribute = (Attr) node;
    		String value = attribute.getValue();
    		return value;
    	}
    
    }
    sample.xml
    Code:
    <foo>
      <bar id="1"/>
      <bar id="2"/>
    </foo>
    output
    Code:
    <foo>
      <bar id="1"/>
      <bar id="2"/>
    </foo>
    [id="1", id="2"]
    1
    Last edited by samdengler; Mar 27th, 2012, 05:36 PM.

  • #2
    The chained splitter-transformer-aggregator works, and is pretty concise, but it would be nice if this could be supported within XPathTransformer. Below is my updated configuration and the output.

    context.xml
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans
    	xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:int="http://www.springframework.org/schema/integration"
    	xmlns:int-stream="http://www.springframework.org/schema/integration/stream"
    	xmlns:int-xml="http://www.springframework.org/schema/integration/xml"
    	xsi:schemaLocation="
    		http://www.springframework.org/schema/integration/xml
    		http://www.springframework.org/schema/integration/xml/spring-integration-xml.xsd
    		http://www.springframework.org/schema/integration/stream
    		http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd
    		http://www.springframework.org/schema/beans
    		http://www.springframework.org/schema/beans/spring-beans.xsd
    		http://www.springframework.org/schema/integration
    		http://www.springframework.org/schema/integration/spring-integration.xsd">
    		
    	<int-xml:xpath-transformer input-channel="input" output-channel="stdout" xpath-expression="/foo/bar/@id"
    		evaluation-type="NODE_LIST_RESULT"/>
    	
    	<int:chain input-channel="input-chain" output-channel="stdout">
    		<int-xml:xpath-splitter>
    			<int-xml:xpath-expression expression="/foo/bar"/>
    		</int-xml:xpath-splitter>
    		<int-xml:xpath-transformer xpath-expression="/bar/@id" node-mapper="nodeMapper"/>
    		<int:aggregator/>
    	</int:chain>
    	
    	<bean id="nodeMapper" class="fluid.examples.xml.TestNodeMapper"/>
    	
    	<int-stream:stdout-channel-adapter id="stdout" append-newline="true"/>
    	
    </beans>
    output
    Code:
    <foo>
      <bar id="1"/>
      <bar id="2"/>
    </foo>
    [id="1", id="2"]
    [1, 2]

    Comment

    Working...
    X