拆分 XML 并将其转换为一个或多个 SOAP 信封
Split XML and transform it in one or more SOAP Envelope
TL;DR;序列收到一条 XML 消息,我需要根据收到的 <product>
个标签的数量构建许多 SOAP 信封。
我有一个序列接收以下 XML(消息 1):
<?xml version="1.0" encoding="UTF-8"?>
<pricing>
<product>
<idFF>1</idFF>
<skuPartner>abc</skuPartner>
<original>123</original>
<new>123</new>
</product>
<product>
<idFF>2</idFF>
<skuPartner>aba</skuPartner>
<original>123</original>
<new>123</new>
</product>
<product>
<idFF>3</idFF>
<skuPartner>ae</skuPartner>
<original>123</original>
<new>123</new>
</product>
</pricing>
我想重复此消息,并为每个 <product>
节点使用以下合同调用 SOAP 服务:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:tem="http://tempuri.org/">
<soap:Header/>
<soap:Body>
<tem:ProductPriceUpdate>
<!--Optional:-->
<tem:safeKey>?</tem:safeKey>
<tem:storeId>?</tem:storeId>
<tem:articleId>?</tem:articleId>
<!--Optional:-->
<tem:barcode>?</tem:barcode>
<!--Optional:-->
<tem:sku>?</tem:sku>
<tem:price>?</tem:price>
<tem:discount>?</tem:discount>
</tem:ProductPriceUpdate>
</soap:Body>
</soap:Envelope>
在上面的这条消息中,我需要替换
<tem:articleId>?</tem:articleId>
<tem:sku>?</tem:sku>
<tem:price>?</tem:price>
使用收到的 XML 消息的节点中包含的值
<idFF>1</idFF>
<skuPartner>abc</skuPartner>
<new>123</new>
所以,面对描述的问题我做了(至少尝试过):
- 遍历收到的消息(消息 1)
- 从节点取值
<idFF> <skuPartner> <new>
- 使用 PayloadFactory 构建 SOAP 信封
- 调用 SOAP 服务
我很确定我离解决方案还有点距离。这是我试过的。
<iterate expression="//produto" id="iterateXML" sequential="true xmlns:ns="http://org.apache.synapse/xsd">
<target>
<sequence>
<payloadFactory media-type="xml">
<format>
<ProductPriceUpdate>
<safeKey>nExd8CzMRDo=</safeKey>
<storeId>123</storeId>
<articleId></articleId>
<barcode>1</barcode>
<sku></sku>
<price></price>
<discount>1</discount>
</ProductPriceUpdate>
</format>
<args>
<arg evaluator="xml" expression="//idFF"/>
<arg evaluator="xml" expression="//skuPartner"/>
<arg evaluator="xml" expression="//new"/>
</args>
</payloadFactory>
<callout action="ProductPriceUpdate"
initAxis2ClientOptions="false" serviceURL="http://url-url.url.info/pub/url.asmx">
<source xpath="*"/>
<target key="Result"/>
</callout>
</sequence>
</target>
</iterate>
这是控制台的输出:
[2016-02-11 11:04:52,982] ERROR - SequenceMediator Expecting an implementation of SOAP Envelope as the parent. But received some other implementation
org.apache.axiom.soap.SOAPProcessingException: Expecting an implementation of SOAP Envelope as the parent. But received some other implementation
at org.apache.axiom.soap.impl.llom.SOAPHeaderImpl.checkParent(SOAPHeaderImpl.java:408)
at org.apache.axiom.soap.impl.llom.SOAPElement.setParent(SOAPElement.java:81)
at org.apache.axiom.om.impl.llom.OMElementImpl.addChild(OMElementImpl.java:296)
at org.apache.axiom.om.impl.llom.OMElementImpl.addChild(OMElementImpl.java:212)
at org.apache.axiom.soap.impl.llom.SOAPBodyImpl.addChild(SOAPBodyImpl.java:231)
at org.apache.synapse.mediators.builtin.CalloutMediator.mediate(CalloutMediator.java:161)
at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:81)
at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:48)
at org.apache.synapse.mediators.base.SequenceMediator.mediate(SequenceMediator.java:149)
at org.apache.synapse.mediators.eip.Target.mediate(Target.java:106)
at org.apache.synapse.mediators.eip.splitter.IterateMediator.mediate(IterateMediator.java:163)
at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:81)
at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:48)
at org.apache.synapse.mediators.base.SequenceMediator.mediate(SequenceMediator.java:149)
at org.apache.synapse.mediators.MediatorWorker.run(MediatorWorker.java:69)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
[2016-02-11 11:04:53,031] INFO - LogMediator To: , WSAction: urn:mediate, SOAPAction: urn:mediate, MessageID: urn:uuid:481ca0ce-8502-486a-b501-350bda23f263, Di
rection: request, MESSAGE = Executing default 'fault' sequence, ERROR_CODE = 0, ERROR_MESSAGE = Expecting an implementation of SOAP Envelope as the parent. But
received some other implementation, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body><pricing>
<product>
<idFF>1</idFF>
<skuPartner>abc</skuPartner>
<original>123</original>
<new>123</new>
</product>
<product>
<idFF>2</idFF>
<skuPartner>aba</skuPartner>
<original>123</original>
<new>123</new>
</product>
<product>
<idFF>3</idFF>
<skuPartner>ae</skuPartner>
<original>123</original>
<new>123</new>
</product>
</pricing></soapenv:Body></soapenv:Envelope>
我错过了什么?我是否应该使用其他调解器,例如 Enrich?
我感谢每一个提示,谢谢。 =)
编辑:
按照@Jean-Michel 的建议,我替换了 callout mediator 中的 xpath 表达式和 SOAP 实现的错误,消失了。虽然我仍然无法满足要求。当我转到我的 WSO2 的监视器 -> SOAP 跟踪时,我看到以下请求:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<text xmlns="http://ws.apache.org/commons/ns/payload">IDFF;SKUPARTNER;ORIGINAL;NEW
11035073;BOBSKU11035073;185.99;200
</text>
</soapenv:Body>
</soapenv:Envelope>
编辑 2:
经过一些修改,我才意识到我在标注调解器中发送的消息与我在序列开头收到的 SOAP 信封内的消息相同。如下(请不要考虑xpath错误,这是故意的):
[2016-02-11 12:44:43,197] INFO - LogMediator To: , WSAction: urn:mediate, SOAPAction: urn:mediate, MessageID: urn:uuid:c3bda9c7-157e-46db-ae9f-f5b687d11848, Di
rection: request, MESSAGE = Executing default 'fault' sequence, ERROR_CODE = 0, ERROR_MESSAGE = The evaluation of the XPath expression : body did not result in
an OMElement, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><pricing>
<product>
<idFF>1</idFF>
<skuPartner>abc</skuPartner>
<original>123</original>
<new>123</new>
</product>
<product>
<idFF>2</idFF>
<skuPartner>aba</skuPartner>
<original>123</original>
<new>123</new>
</product>
<product>
<idFF>3</idFF>
<skuPartner>ae</skuPartner>
<original>123</original>
<new>123</new>
</product>
</pricing></soapenv:Body></soapenv:Envelope>
编辑 3:
我将标注的地址更改为 http://localhost:1205,这是使用 TCPMon 的结果。似乎一切都还好。
我没有使用标注调解器,但是 <source xpath="*"/>
看起来很奇怪:它的意思是 "all nodes for the source payload"(必须发送的消息)。
您应该考虑像 <source xpath="$body/*[1]"/>
这样的东西来发送第一个主体的 child(即当前肥皂主体的内容),例如...
我能够解决问题。谢谢@Jean-Michel 帮助我度过难关。
我做了以下事情:
- 创建了直通代理
- 将 Callout Mediator 更改为调用 PassThroug Proxy 的 Send Mediator
- 添加了 Header 调解器并定义了 SOAP 操作 - 最重要!
在这里你可以找到我的WSO2-Config.XML:
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://ws.apache.org/ns/synapse">
<registry provider="org.wso2.carbon.mediation.registry.WSO2Registry">
<parameter name="cachableDuration">15000</parameter>
</registry>
<taskManager provider="org.wso2.carbon.mediation.ntask.NTaskTaskManager"/>
<proxy name="smook_proxy" startOnLoad="true" trace="disable" transports="https http vfs">
<description/>
<target>
<inSequence>
<property name="FORCE_SC_ACCEPTED" scope="axis2"
type="STRING" value="true"/>
<property name="OUT_ONLY" scope="default" type="STRING" value="true"/>
<clone>
<target sequence="pricing"/>
</clone>
</inSequence>
</target>
<parameter name="transport.PollInterval">5</parameter>
<parameter name="transport.vfs.ActionAfterProcess">MOVE</parameter>
<parameter name="transport.vfs.MoveAfterProcess">file:///C:\Users\victor.viola\Desktop\out</parameter>
<parameter name="transport.vfs.FileURI">file:///C:\Users\victor.viola\Desktop\in</parameter>
<parameter name="transport.vfs.MoveAfterFailure">file:///C:\Users\victor.viola\Desktop\error</parameter>
<parameter name="transport.vfs.FileNamePattern">.*.csv</parameter>
<parameter name="transport.vfs.ContentType">text/plain</parameter>
<parameter name="transport.vfs.ActionAfterFailure">MOVE</parameter>
</proxy>
<proxy name="PS_PRICING" startOnLoad="true" trace="disable" transports="https http">
<description/>
<target>
<endpoint name="wsFF">
<address trace="disable" uri="ADRESSTOTHEBACKEND.asmx"/>
</endpoint>
<inSequence/>
<outSequence>
<send/>
</outSequence>
<faultSequence/>
</target>
</proxy>
<localEntry key="smooks-csv.xml" src="file:C:/wso2esb-4.9.0/repository/resources/smooks/smooks-csv.xml">
<description/>
</localEntry>
<endpoint name="PS_PRICING">
<address uri="http://localhost:8280/services/PS_PRICING"/>
</endpoint>
<sequence name="pricing" statistics="enable" trace="enable">
<smooks config-key="smooks-csv.xml">
<input type="text"/>
<output type="xml"/>
</smooks>
<iterate expression="//product" id="iterateXML"
sequential="true" xmlns:ns="http://org.apache.synapse/xsd">
<target>
<sequence>
<payloadFactory media-type="xml">
<format>
<ProductPriceUpdate>
<safeKey>******</safeKey>
<storeId>*****</storeId>
<articleId></articleId>
<barcode/>
<sku></sku>
<price></price>
<discount>100</discount>
</ProductPriceUpdate>
</format>
<args>
<arg evaluator="xml" expression="//idFF"/>
<arg evaluator="xml" expression="//skuPartner"/>
<arg evaluator="xml" expression="//new"/>
</args>
</payloadFactory>
<property name="messageType" scope="axis2" value="text/xml"/>
<in>
<header name="Action" scope="default" value="http://tempuri.org/ProductPriceUpdate"/>
<send>
<endpoint key="PS_PRICING"/>
</send>
<drop/>
</in>
<out>
<send/>
</out>
</sequence>
</target>
</iterate>
</sequence>
</definitions>
这是我的smooks.xml
<?xml version="1.0" encoding="UTF-8"?><smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd" xmlns:csv="http://www.milyn.org/xsd/smooks/csv-1.2.xsd" xmlns:ftl="http://www.milyn.org/xsd/smooks/freemarker-1.1.xsd" xmlns:file="http://www.milyn.org/xsd/smooks/file-routing-1.1.xsd">
<params>
<param name="stream.filter.type">SAX</param>
<param name="default.serialization.on">true</param>
</params>
<csv:reader fields="idFF,skuPartner,original,new" separator=";" skipLines="1"/>
<ftl:freemarker applyOnElement="#document">
<ftl:template><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<pricing>
<#list .vars["csv-set"]["csv-record"] as csv_record>
<product>
<idFF>${.vars["csv_record"]["idFF"]}</idFF>
<skuPartner>${.vars["csv_record"]["skuPartner"]}</skuPartner>
<original>${.vars["csv_record"]["original"]}</original>
<new>${.vars["csv_record"]["new"]}</new>
</product>
</#list>
</pricing>]]></ftl:template>
</ftl:freemarker>
<resource-config selector="#document">
<resource>org.milyn.delivery.DomModelCreator</resource>
</resource-config>
</smooks-resource-list>
另一件对解决问题非常重要的事情是在 log4j.properties (wso2home/repository/conf)
中启用这两个日志
log4j.logger.org.apache.synapse.transport.http.headers=DEBUG
log4j.logger.org.apache.synapse.transport.http.wire=DEBUG
TL;DR;序列收到一条 XML 消息,我需要根据收到的 <product>
个标签的数量构建许多 SOAP 信封。
我有一个序列接收以下 XML(消息 1):
<?xml version="1.0" encoding="UTF-8"?>
<pricing>
<product>
<idFF>1</idFF>
<skuPartner>abc</skuPartner>
<original>123</original>
<new>123</new>
</product>
<product>
<idFF>2</idFF>
<skuPartner>aba</skuPartner>
<original>123</original>
<new>123</new>
</product>
<product>
<idFF>3</idFF>
<skuPartner>ae</skuPartner>
<original>123</original>
<new>123</new>
</product>
</pricing>
我想重复此消息,并为每个 <product>
节点使用以下合同调用 SOAP 服务:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:tem="http://tempuri.org/">
<soap:Header/>
<soap:Body>
<tem:ProductPriceUpdate>
<!--Optional:-->
<tem:safeKey>?</tem:safeKey>
<tem:storeId>?</tem:storeId>
<tem:articleId>?</tem:articleId>
<!--Optional:-->
<tem:barcode>?</tem:barcode>
<!--Optional:-->
<tem:sku>?</tem:sku>
<tem:price>?</tem:price>
<tem:discount>?</tem:discount>
</tem:ProductPriceUpdate>
</soap:Body>
</soap:Envelope>
在上面的这条消息中,我需要替换
<tem:articleId>?</tem:articleId>
<tem:sku>?</tem:sku>
<tem:price>?</tem:price>
使用收到的 XML 消息的节点中包含的值
<idFF>1</idFF>
<skuPartner>abc</skuPartner>
<new>123</new>
所以,面对描述的问题我做了(至少尝试过):
- 遍历收到的消息(消息 1)
- 从节点取值
<idFF> <skuPartner> <new>
- 使用 PayloadFactory 构建 SOAP 信封
- 调用 SOAP 服务
我很确定我离解决方案还有点距离。这是我试过的。
<iterate expression="//produto" id="iterateXML" sequential="true xmlns:ns="http://org.apache.synapse/xsd">
<target>
<sequence>
<payloadFactory media-type="xml">
<format>
<ProductPriceUpdate>
<safeKey>nExd8CzMRDo=</safeKey>
<storeId>123</storeId>
<articleId></articleId>
<barcode>1</barcode>
<sku></sku>
<price></price>
<discount>1</discount>
</ProductPriceUpdate>
</format>
<args>
<arg evaluator="xml" expression="//idFF"/>
<arg evaluator="xml" expression="//skuPartner"/>
<arg evaluator="xml" expression="//new"/>
</args>
</payloadFactory>
<callout action="ProductPriceUpdate"
initAxis2ClientOptions="false" serviceURL="http://url-url.url.info/pub/url.asmx">
<source xpath="*"/>
<target key="Result"/>
</callout>
</sequence>
</target>
</iterate>
这是控制台的输出:
[2016-02-11 11:04:52,982] ERROR - SequenceMediator Expecting an implementation of SOAP Envelope as the parent. But received some other implementation
org.apache.axiom.soap.SOAPProcessingException: Expecting an implementation of SOAP Envelope as the parent. But received some other implementation
at org.apache.axiom.soap.impl.llom.SOAPHeaderImpl.checkParent(SOAPHeaderImpl.java:408)
at org.apache.axiom.soap.impl.llom.SOAPElement.setParent(SOAPElement.java:81)
at org.apache.axiom.om.impl.llom.OMElementImpl.addChild(OMElementImpl.java:296)
at org.apache.axiom.om.impl.llom.OMElementImpl.addChild(OMElementImpl.java:212)
at org.apache.axiom.soap.impl.llom.SOAPBodyImpl.addChild(SOAPBodyImpl.java:231)
at org.apache.synapse.mediators.builtin.CalloutMediator.mediate(CalloutMediator.java:161)
at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:81)
at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:48)
at org.apache.synapse.mediators.base.SequenceMediator.mediate(SequenceMediator.java:149)
at org.apache.synapse.mediators.eip.Target.mediate(Target.java:106)
at org.apache.synapse.mediators.eip.splitter.IterateMediator.mediate(IterateMediator.java:163)
at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:81)
at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:48)
at org.apache.synapse.mediators.base.SequenceMediator.mediate(SequenceMediator.java:149)
at org.apache.synapse.mediators.MediatorWorker.run(MediatorWorker.java:69)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
[2016-02-11 11:04:53,031] INFO - LogMediator To: , WSAction: urn:mediate, SOAPAction: urn:mediate, MessageID: urn:uuid:481ca0ce-8502-486a-b501-350bda23f263, Di
rection: request, MESSAGE = Executing default 'fault' sequence, ERROR_CODE = 0, ERROR_MESSAGE = Expecting an implementation of SOAP Envelope as the parent. But
received some other implementation, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body><pricing>
<product>
<idFF>1</idFF>
<skuPartner>abc</skuPartner>
<original>123</original>
<new>123</new>
</product>
<product>
<idFF>2</idFF>
<skuPartner>aba</skuPartner>
<original>123</original>
<new>123</new>
</product>
<product>
<idFF>3</idFF>
<skuPartner>ae</skuPartner>
<original>123</original>
<new>123</new>
</product>
</pricing></soapenv:Body></soapenv:Envelope>
我错过了什么?我是否应该使用其他调解器,例如 Enrich? 我感谢每一个提示,谢谢。 =)
编辑:
按照@Jean-Michel 的建议,我替换了 callout mediator 中的 xpath 表达式和 SOAP 实现的错误,消失了。虽然我仍然无法满足要求。当我转到我的 WSO2 的监视器 -> SOAP 跟踪时,我看到以下请求:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<text xmlns="http://ws.apache.org/commons/ns/payload">IDFF;SKUPARTNER;ORIGINAL;NEW
11035073;BOBSKU11035073;185.99;200
</text>
</soapenv:Body>
</soapenv:Envelope>
编辑 2:
经过一些修改,我才意识到我在标注调解器中发送的消息与我在序列开头收到的 SOAP 信封内的消息相同。如下(请不要考虑xpath错误,这是故意的):
[2016-02-11 12:44:43,197] INFO - LogMediator To: , WSAction: urn:mediate, SOAPAction: urn:mediate, MessageID: urn:uuid:c3bda9c7-157e-46db-ae9f-f5b687d11848, Di
rection: request, MESSAGE = Executing default 'fault' sequence, ERROR_CODE = 0, ERROR_MESSAGE = The evaluation of the XPath expression : body did not result in
an OMElement, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><pricing>
<product>
<idFF>1</idFF>
<skuPartner>abc</skuPartner>
<original>123</original>
<new>123</new>
</product>
<product>
<idFF>2</idFF>
<skuPartner>aba</skuPartner>
<original>123</original>
<new>123</new>
</product>
<product>
<idFF>3</idFF>
<skuPartner>ae</skuPartner>
<original>123</original>
<new>123</new>
</product>
</pricing></soapenv:Body></soapenv:Envelope>
编辑 3:
我将标注的地址更改为 http://localhost:1205,这是使用 TCPMon 的结果。似乎一切都还好。
我没有使用标注调解器,但是 <source xpath="*"/>
看起来很奇怪:它的意思是 "all nodes for the source payload"(必须发送的消息)。
您应该考虑像 <source xpath="$body/*[1]"/>
这样的东西来发送第一个主体的 child(即当前肥皂主体的内容),例如...
我能够解决问题。谢谢@Jean-Michel 帮助我度过难关。
我做了以下事情:
- 创建了直通代理
- 将 Callout Mediator 更改为调用 PassThroug Proxy 的 Send Mediator
- 添加了 Header 调解器并定义了 SOAP 操作 - 最重要!
在这里你可以找到我的WSO2-Config.XML:
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://ws.apache.org/ns/synapse">
<registry provider="org.wso2.carbon.mediation.registry.WSO2Registry">
<parameter name="cachableDuration">15000</parameter>
</registry>
<taskManager provider="org.wso2.carbon.mediation.ntask.NTaskTaskManager"/>
<proxy name="smook_proxy" startOnLoad="true" trace="disable" transports="https http vfs">
<description/>
<target>
<inSequence>
<property name="FORCE_SC_ACCEPTED" scope="axis2"
type="STRING" value="true"/>
<property name="OUT_ONLY" scope="default" type="STRING" value="true"/>
<clone>
<target sequence="pricing"/>
</clone>
</inSequence>
</target>
<parameter name="transport.PollInterval">5</parameter>
<parameter name="transport.vfs.ActionAfterProcess">MOVE</parameter>
<parameter name="transport.vfs.MoveAfterProcess">file:///C:\Users\victor.viola\Desktop\out</parameter>
<parameter name="transport.vfs.FileURI">file:///C:\Users\victor.viola\Desktop\in</parameter>
<parameter name="transport.vfs.MoveAfterFailure">file:///C:\Users\victor.viola\Desktop\error</parameter>
<parameter name="transport.vfs.FileNamePattern">.*.csv</parameter>
<parameter name="transport.vfs.ContentType">text/plain</parameter>
<parameter name="transport.vfs.ActionAfterFailure">MOVE</parameter>
</proxy>
<proxy name="PS_PRICING" startOnLoad="true" trace="disable" transports="https http">
<description/>
<target>
<endpoint name="wsFF">
<address trace="disable" uri="ADRESSTOTHEBACKEND.asmx"/>
</endpoint>
<inSequence/>
<outSequence>
<send/>
</outSequence>
<faultSequence/>
</target>
</proxy>
<localEntry key="smooks-csv.xml" src="file:C:/wso2esb-4.9.0/repository/resources/smooks/smooks-csv.xml">
<description/>
</localEntry>
<endpoint name="PS_PRICING">
<address uri="http://localhost:8280/services/PS_PRICING"/>
</endpoint>
<sequence name="pricing" statistics="enable" trace="enable">
<smooks config-key="smooks-csv.xml">
<input type="text"/>
<output type="xml"/>
</smooks>
<iterate expression="//product" id="iterateXML"
sequential="true" xmlns:ns="http://org.apache.synapse/xsd">
<target>
<sequence>
<payloadFactory media-type="xml">
<format>
<ProductPriceUpdate>
<safeKey>******</safeKey>
<storeId>*****</storeId>
<articleId></articleId>
<barcode/>
<sku></sku>
<price></price>
<discount>100</discount>
</ProductPriceUpdate>
</format>
<args>
<arg evaluator="xml" expression="//idFF"/>
<arg evaluator="xml" expression="//skuPartner"/>
<arg evaluator="xml" expression="//new"/>
</args>
</payloadFactory>
<property name="messageType" scope="axis2" value="text/xml"/>
<in>
<header name="Action" scope="default" value="http://tempuri.org/ProductPriceUpdate"/>
<send>
<endpoint key="PS_PRICING"/>
</send>
<drop/>
</in>
<out>
<send/>
</out>
</sequence>
</target>
</iterate>
</sequence>
</definitions>
这是我的smooks.xml
<?xml version="1.0" encoding="UTF-8"?><smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd" xmlns:csv="http://www.milyn.org/xsd/smooks/csv-1.2.xsd" xmlns:ftl="http://www.milyn.org/xsd/smooks/freemarker-1.1.xsd" xmlns:file="http://www.milyn.org/xsd/smooks/file-routing-1.1.xsd">
<params>
<param name="stream.filter.type">SAX</param>
<param name="default.serialization.on">true</param>
</params>
<csv:reader fields="idFF,skuPartner,original,new" separator=";" skipLines="1"/>
<ftl:freemarker applyOnElement="#document">
<ftl:template><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<pricing>
<#list .vars["csv-set"]["csv-record"] as csv_record>
<product>
<idFF>${.vars["csv_record"]["idFF"]}</idFF>
<skuPartner>${.vars["csv_record"]["skuPartner"]}</skuPartner>
<original>${.vars["csv_record"]["original"]}</original>
<new>${.vars["csv_record"]["new"]}</new>
</product>
</#list>
</pricing>]]></ftl:template>
</ftl:freemarker>
<resource-config selector="#document">
<resource>org.milyn.delivery.DomModelCreator</resource>
</resource-config>
</smooks-resource-list>
另一件对解决问题非常重要的事情是在 log4j.properties (wso2home/repository/conf)
中启用这两个日志log4j.logger.org.apache.synapse.transport.http.headers=DEBUG
log4j.logger.org.apache.synapse.transport.http.wire=DEBUG