如何使用enrich with foreach/iterate修改SOAP请求体?

How to use enrich with foreach/iterate to modify SOAP request body?

我想从 JSON 输入数组向 SOAP 请求正文添加多个标签。

应该加在ActionProperties标签下,所以我尝试使用foreach的enrich mediator如下:

<payloadFactory media-type="xml">
            <format>
                <soapenv:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
                xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
                xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                    <soapenv:Header>
                        <Security xmlns="http://schemas.xmlsoap.org/ws/2002/12/secext">
                            <hd:UsernameToken xmlns:hd="http://schemas.xmlsoap.org/ws/2002/12/secext">
                                <hd:Username></hd:Username>
                                <hd:Password></hd:Password>
                            </hd:UsernameToken>
                        </Security>
                    </soapenv:Header>
                    <soapenv:Body>
                        <p857:ExecuteChangesRequest refresh="1" xmlns:p857="http://www.filenet.com/ns/fnce/2006/11/ws/schema">
                            <p857:ChangeRequest id="1" updateSequenceNumber="0">
                                <p857:TargetSpecification classId="ObjectStore" objectId="" serializationDuplicate="0"/>
                                <p857:Action autoUniqueContainmentName="1" classId="" defineSecurityParentage="0" xsi:type="p857:CreateAction"/>
                                <p857:Action autoClassify="0" checkinMinorVersion="0" xsi:type="p857:CheckinAction"/>
                                <p857:ActionProperties>

                                    <p857:Property propertyId="DocumentTitle" settable="0" xsi:type="p857:SingletonString">
                                        <p857:Value></p857:Value>
                                    </p857:Property>
                                    <p857:Property propertyId="ContentElements" settable="0" xsi:type="p857:ListOfObject">
                                        <p857:Value accessAllowed="0" classId="ContentTransfer" dependentAction="Insert" newIndex="0" originalIndex="0" serializationDuplicate="0" updateSequenceNumber="0">
                                            <p857:Property propertyId="ContentType" settable="0" xsi:type="p857:SingletonString">
                                                <p857:Value></p857:Value>
                                            </p857:Property>
                                            <p857:Property propertyId="RetrievalName" settable="0" xsi:type="p857:SingletonString">
                                                <p857:Value></p857:Value>
                                            </p857:Property>
                                            <p857:Property propertyId="Content" settable="0" xsi:type="p857:ContentData">
                                                <p857:Value xsi:type="p857:InlineContent">
                                                    <p857:Binary></p857:Binary>
                                                </p857:Value>
                                            </p857:Property>
                                        </p857:Value>
                                    </p857:Property>
                                </p857:ActionProperties>
                                <p857:RefreshFilter levelDependents="0" maxElements="0" maxRecursion="0">
                                    <p857:ExcludeProperties>DateCreated</p857:ExcludeProperties>
                                    <p857:ExcludeProperties>DateLastModified</p857:ExcludeProperties>
                                </p857:RefreshFilter>
                            </p857:ChangeRequest>
                        </p857:ExecuteChangesRequest>
                    </soapenv:Body>
                </soapenv:Envelope>
            </format>
            <args>
                <arg evaluator="xml" expression="get-property('Username')"/>
                <arg evaluator="xml" expression="get-property('Password')"/>
                <arg evaluator="xml" expression="get-property('ObjectStore')"/>
                <arg evaluator="xml" expression="get-property('DocumentClass')"/>
                <arg evaluator="xml" expression="get-property('FileName')"/>
                <arg evaluator="xml" expression="get-property('FileData')"/>
                <arg evaluator="xml" expression="get-property('ContentType')"/>
            </args>
        </payloadFactory>

<foreach expression="//propertiesList">
        <target>
        <sequence>
               <enrich>
                   <source clone="true" type="inline">                                             
                   <p857:Property propertyId="" settable="0" 
                    xmlns:p857="http://www.filenet.com/ns/fnce/2006/11/ws/schema" 
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="p857:SingletonString">
                        <p857:Value></p857:Value>
                    </p857:Property>
                   <args>
                        <arg evaluator="xml" expression="//name"/>
                        <arg evaluator="xml" expression="//value"/>
                    </args>
                    </source>
                    <target action="child" xmlns:p857="http://www.filenet.com/ns/fnce/2006/11/ws/schema" 
                     xpath="//p857:ExecuteChangesRequest/p857:ChangeRequest/p857:ActionProperties"/>
                </enrich>                                                                                                                                           
        </sequence>
        </target>
    </foreach>

但是 SOAP 请求中没有插入任何内容。而如果我尝试丰富单个标签,它可以正常工作,如下所示:

<enrich>
        <source clone="true" type="inline">
            <p857:Property propertyId="isArchived" settable="0" 
            xmlns:p857="http://www.filenet.com/ns/fnce/2006/11/ws/schema" 
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="p857:SingletonString">
                <p857:Value>1</p857:Value>
            </p857:Property>
        </source>
        <target action="child" xmlns:p857="http://www.filenet.com/ns/fnce/2006/11/ws/schema" 
        xpath="//p857:ExecuteChangesRequest/p857:ChangeRequest/p857:ActionProperties"/>
    </enrich>

我怎样才能做到这一点?

解决方案 01:使用 Foreach 和 Payload Factory 以下应该做你正在寻找的东西。由于我不知道您的 属性 列表是如何集成到集成中的,所以我只是对其进行了硬编码。

<inSequence>
            <payloadFactory media-type="xml">
                <format>
                    <propertiesList xmlns="">
                        <property>
                            <name>12345</name>
                        </property>
                        <property>
                            <name>23456</name>
                        </property>
                        <property>
                            <name>34567</name>
                        </property>
                    </propertiesList>
                </format>
                <args/>
            </payloadFactory>
            <foreach expression="//propertiesList/property">
                <sequence>
                    <log level="custom">
                        <property name="XXXX" value="In the for each....."/>
                    </log>
                    <payloadFactory media-type="xml">
                        <format>
                            <p857:Property propertyId="" settable="0" xmlns:p857="http://www.filenet.com/ns/fnce/2006/11/ws/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="p857:SingletonString">
                                <p857:Value></p857:Value>
                            </p857:Property>
                        </format>
                        <args>
                            <arg evaluator="xml" expression="//name"/>
                            <arg evaluator="xml" expression="//value"/>
                        </args>
                    </payloadFactory>
                </sequence>
            </foreach>
            <log level="full"/>
            <enrich>
                <source clone="true" type="body"/>
                <target property="ConvertedPropertiesList" type="property"/>
            </enrich>
            <payloadFactory media-type="xml">
                <format>
                    <soapenv:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                        <soapenv:Header>
                            <Security xmlns="http://schemas.xmlsoap.org/ws/2002/12/secext">
                                <hd:UsernameToken xmlns:hd="http://schemas.xmlsoap.org/ws/2002/12/secext">
                                    <hd:Username></hd:Username>
                                    <hd:Password></hd:Password>
                                </hd:UsernameToken>
                            </Security>
                        </soapenv:Header>
                        <soapenv:Body>
                            <p857:ExecuteChangesRequest refresh="1" xmlns:p857="http://www.filenet.com/ns/fnce/2006/11/ws/schema">
                                <p857:ChangeRequest id="1" updateSequenceNumber="0">
                                    <p857:TargetSpecification classId="ObjectStore" objectId="" serializationDuplicate="0"/>
                                    <p857:Action autoUniqueContainmentName="1" classId="" defineSecurityParentage="0" xsi:type="p857:CreateAction"/>
                                    <p857:Action autoClassify="0" checkinMinorVersion="0" xsi:type="p857:CheckinAction"/>
                                    <p857:ActionProperties>
                                        <p857:Property propertyId="DocumentTitle" settable="0" xsi:type="p857:SingletonString">
                                            <p857:Value></p857:Value>
                                        </p857:Property>
                                        <p857:Property propertyId="ContentElements" settable="0" xsi:type="p857:ListOfObject">
                                            <p857:Value accessAllowed="0" classId="ContentTransfer" dependentAction="Insert" newIndex="0" originalIndex="0" serializationDuplicate="0" updateSequenceNumber="0">
                                                <p857:Property propertyId="ContentType" settable="0" xsi:type="p857:SingletonString">
                                                    <p857:Value></p857:Value>
                                                </p857:Property>
                                                <p857:Property propertyId="RetrievalName" settable="0" xsi:type="p857:SingletonString">
                                                    <p857:Value></p857:Value>
                                                </p857:Property>
                                                <p857:Property propertyId="Content" settable="0" xsi:type="p857:ContentData">
                                                    <p857:Value xsi:type="p857:InlineContent">
                                                        <p857:Binary></p857:Binary>
                                                    </p857:Value>
                                                </p857:Property>
                                            </p857:Value>
                                        </p857:Property>
                                        
                                    </p857:ActionProperties>
                                    <p857:RefreshFilter levelDependents="0" maxElements="0" maxRecursion="0">
                                        <p857:ExcludeProperties>DateCreated</p857:ExcludeProperties>
                                        <p857:ExcludeProperties>DateLastModified</p857:ExcludeProperties>
                                    </p857:RefreshFilter>
                                </p857:ChangeRequest>
                            </p857:ExecuteChangesRequest>
                        </soapenv:Body>
                    </soapenv:Envelope>
                </format>
                <args>
                    <arg evaluator="xml" expression="get-property('Username')"/>
                    <arg evaluator="xml" expression="get-property('Password')"/>
                    <arg evaluator="xml" expression="get-property('ObjectStore')"/>
                    <arg evaluator="xml" expression="get-property('DocumentClass')"/>
                    <arg evaluator="xml" expression="get-property('FileName')"/>
                    <arg evaluator="xml" expression="get-property('FileData')"/>
                    <arg evaluator="xml" expression="get-property('ContentType')"/>
                    <arg evaluator="xml" expression="$ctx:ConvertedPropertiesList//p857:Property" xmlns:p857="http://www.filenet.com/ns/fnce/2006/11/ws/schema" />
                </args>
            </payloadFactory>
            <log level="full"/>
        </inSequence>

解决方案 02:XSLT 调解器 我认为最优雅的方法是使用 XSLT 调解器。以下是您可以如何使用 XSLT 调解器。

首先,创建一个 XSLT 模板作为本地条目。使用以下示例。

<?xml version="1.0" encoding="UTF-8"?>
<localEntry key="xsltTransformer" xmlns="http://ws.apache.org/ns/synapse">
    <xsl:stylesheet version="1.0" xmlns:ns4="http://nmdp.org/esb/domain/v04" xmlns:ns7="http://nmdp.org/esb/domain/v02" xmlns:ns8="http://nmdp.org/esb/domain/v01" xmlns:sfdc="sfdc" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output encoding="UTF-8" indent="yes" method="xml" omit-xml-declaration="yes"/>
        <xsl:param name="Username"/>
        <xsl:param name="Password"/>
        <xsl:template match="/">
            <payload xmlns="">
                <soapenv:Envelope
    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Header>
        <Security
            xmlns="http://schemas.xmlsoap.org/ws/2002/12/secext">
            <hd:UsernameToken
                xmlns:hd="http://schemas.xmlsoap.org/ws/2002/12/secext">
                <hd:Username>
                    <xsl:value-of select="$Username"/>
                </hd:Username>
                <hd:Password>
                    <xsl:value-of select="$Password"/>
                </hd:Password>
            </hd:UsernameToken>
        </Security>
    </soapenv:Header>
    <soapenv:Body>
        <p857:ExecuteChangesRequest refresh="1"
            xmlns:p857="http://www.filenet.com/ns/fnce/2006/11/ws/schema">
            <p857:ChangeRequest id="1" updateSequenceNumber="0">
                <p857:TargetSpecification classId="ObjectStore" objectId="" serializationDuplicate="0"/>
                <p857:Action autoUniqueContainmentName="1" classId="" defineSecurityParentage="0" xsi:type="p857:CreateAction"/>
                <p857:Action autoClassify="0" checkinMinorVersion="0" xsi:type="p857:CheckinAction"/>
                <p857:ActionProperties>
                    <p857:Property propertyId="DocumentTitle" settable="0" xsi:type="p857:SingletonString">
                        <p857:Value></p857:Value>
                    </p857:Property>
                    <p857:Property propertyId="ContentElements" settable="0" xsi:type="p857:ListOfObject">
                        <p857:Value accessAllowed="0" classId="ContentTransfer" dependentAction="Insert" newIndex="0" originalIndex="0" serializationDuplicate="0" updateSequenceNumber="0">
                            <p857:Property propertyId="ContentType" settable="0" xsi:type="p857:SingletonString">
                                <p857:Value></p857:Value>
                            </p857:Property>
                            <p857:Property propertyId="RetrievalName" settable="0" xsi:type="p857:SingletonString">
                                <p857:Value></p857:Value>
                            </p857:Property>
                            <p857:Property propertyId="Content" settable="0" xsi:type="p857:ContentData">
                                <p857:Value xsi:type="p857:InlineContent">
                                    <p857:Binary></p857:Binary>
                                </p857:Value>
                            </p857:Property>
                        </p857:Value>
                    </p857:Property>
                    <xsl:for-each select="//propertiesList/property">
                        <p857:Property propertyId="{name}" settable="0"
                            xmlns:p857="http://www.filenet.com/ns/fnce/2006/11/ws/schema"
                            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="p857:SingletonString">
                            <p857:Value>
                                <xsl:value-of select="value"/>
                            </p857:Value>
                        </p857:Property>
                    </xsl:for-each>
                </p857:ActionProperties>
                <p857:RefreshFilter levelDependents="0" maxElements="0" maxRecursion="0">
                    <p857:ExcludeProperties>DateCreated</p857:ExcludeProperties>
                    <p857:ExcludeProperties>DateLastModified</p857:ExcludeProperties>
                </p857:RefreshFilter>
            </p857:ChangeRequest>
        </p857:ExecuteChangesRequest>
    </soapenv:Body>
</soapenv:Envelope>
            </payload>
       </xsl:template>
    </xsl:stylesheet>
</localEntry>

那你可以在主序中参考上面的内容

<?xml version="1.0" encoding="UTF-8"?>
<api context="/xslt" name="xslt" xmlns="http://ws.apache.org/ns/synapse">
    <resource methods="GET">
        <inSequence>
            <log/>
            <property name="username" value="abcd"></property>
            <property name="pass" value="1233456"></property>
            <payloadFactory media-type="xml">
                <format>
                    <propertiesList xmlns="">
                        <property>
                            <name>12345</name>
                        </property>
                        <property>
                            <name>23456</name>
                        </property>
                        <property>
                            <name>34567</name>
                        </property>
                    </propertiesList>
                </format>
                <args/>
            </payloadFactory>
            <xslt key="xsltTransformer">
                <property name="Username" expression="$ctx:username"></property>
                <property name="Password" expression="$ctx:pass"></property>
            </xslt>
            <log level="full"></log>
        </inSequence>
        <outSequence/>
        <faultSequence/>
    </resource>
</api>