Question

I receive a message from AAA nested children. I want every child BBB replace the value of CCC. Then send the modified message on AAA

<AAA>
    <BBB>
        <CCC>test1</CCC>
        <DDD>testing</DDD>
    </BBB>
    <BBB>
        <CCC>test2</CCC>
        <DDD>testing</DDD>
    </BBB>
    <BBB>
        <CCC>test3</CCC>
        <DDD>testing</DDD>
    </BBB>
    <BBB>
        <CCC>test4</CCC>
        <DDD>testing</DDD>
    </BBB>
    <BBB>
        <CCC>test5</CCC>
        <DDD>testing</DDD>
    </BBB>
</AAA>

I do it:

<iterate continueParent="true" expression="/AAA/BBB">
    <target>
        <sequence>
            <property name="newValue" value="chang testing" scope="default" type="STRING"/>
            <enrich>
                <source clone="false" type="custom" xpath="get-property('newValue')"/>
                <target action="replace" type="custom" xpath="//DDD"/>
            </enrich>
         </sequence>
    </target>
</iterate>

But changing the message is not stored on

Was it helpful?

Solution 2

I wrote my mediator and use it for this purpose

import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMNode;
import org.apache.axiom.om.impl.dom.NamespaceImpl;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axis2.AxisFault;
import org.apache.synapse.Mediator;
import org.apache.synapse.MessageContext;
import org.apache.synapse.mediators.AbstractMediator;
import org.apache.synapse.mediators.eip.EIPUtils;
import org.apache.synapse.util.MessageHelper;
import org.apache.synapse.util.xpath.SynapseXPath;
import org.jaxen.JaxenException;

import java.util.List;


public class SplitMediator extends AbstractMediator {

    private String sequenceRef = null;
    private String xpathString = null;
    private String attachPathString = null;
    private String uri = null;
    private String prefix = null;

    public boolean mediate(MessageContext synCtx) {
        if (sequenceRef == null || xpathString == null || attachPathString == null) {
            handleException("Error creating a mediate due to sequenceRef or xpathString  attachPathString is null", synCtx);
            return false;
        }

        try {
            SOAPEnvelope envelope = synCtx.getEnvelope();
            Mediator sequenceMediator = synCtx.getSequence(sequenceRef);

            SynapseXPath expression = new SynapseXPath(xpathString);
            if (uri != null && prefix != null)
                expression.addNamespace(new NamespaceImpl(uri, prefix));
            SynapseXPath attachPath = new SynapseXPath(attachPathString);
            if (uri != null && prefix != null)
                attachPath.addNamespace(new NamespaceImpl(uri, prefix));

            List<OMNode> splitElements = EIPUtils.getDetachedMatchingElements(envelope, synCtx, expression);
            MessageContext templateMessageContext = MessageHelper.cloneMessageContext(synCtx);
            OMElement omElement = getOMElementByXPath(attachPath, envelope, synCtx);

            for (OMNode o : splitElements) {
                 MessageContext changeCtx = getNewMessageContextToSequence(templateMessageContext, o, attachPath);
                sequenceMediator.mediate(changeCtx);
                List elementList = EIPUtils.getMatchingElements(changeCtx.getEnvelope(), expression);
                OMNode changeElement = (OMNode) elementList.get(0);
                omElement.addChild(changeElement);
            }
        } catch (JaxenException e) {
            handleException("Error evaluating split XPath expression : " + xpathString, e, synCtx);
        } catch (AxisFault af) {
            handleException("Error creating an iterated copy of the message", af, synCtx);
        }
        return true;
    }

    private MessageContext getNewMessageContextToSequence(MessageContext templateMessageContext, OMNode o, SynapseXPath attachPath) throws AxisFault, JaxenException {
        MessageContext synCtx = MessageHelper.cloneMessageContext(templateMessageContext);
        SOAPEnvelope envelope = synCtx.getEnvelope();
        OMElement omElement = getOMElementByXPath(attachPath, envelope, synCtx);
        omElement.addChild(o);
        return synCtx;
    }

    private OMElement getOMElementByXPath(SynapseXPath attachPath, SOAPEnvelope envelope, MessageContext synCtx) {
        Object attachElem = attachPath.evaluate(envelope, synCtx);
        if (attachElem != null &&
                attachElem instanceof List && !((List) attachElem).isEmpty()) {
            attachElem = ((List) attachElem).get(0);
        }
        // for the moment attaching element should be an OMElement
        if (attachElem != null && attachElem instanceof OMElement) {
            return ((OMElement) attachElem);
        } else {
            handleException("Error in attaching the splitted elements :: " +
                    "Unable to get the attach path specified by the expression " +
                    attachPath, synCtx);
        }
        return null;
    }


    ///////////////////////////////////////////////////////////////////////////////////////
    //                        Getters and Setters                                        //
    ///////////////////////////////////////////////////////////////////////////////////////


    public String getXpathString() {
        return xpathString;
    }

    public void setXpathString(String xpathString) {
        this.xpathString = xpathString;
    }

    public String getAttachPathString() {
        return attachPathString;
    }

    public void setAttachPathString(String attachPathString) {
        this.attachPathString = attachPathString;
    }

    public String getUri() {
        return uri;
    }

    public void setUri(String uri) {
        this.uri = uri;
    }

    public String getPrefix() {
        return prefix;
    }

    public void setPrefix(String prefix) {
        this.prefix = prefix;
    }

    public String getSequenceRef() {
        return sequenceRef;
    }

    public void setSequenceRef(String sequenceRef) {
        this.sequenceRef = sequenceRef;
    }
}

OTHER TIPS

If you use iterate mediator you have to aggregate the results to get the modified message. How ever this can be achieved by using xslt mediator. Sample proxy configuration would be look like follows

<proxy name="yourpproxy" transports="https http" startOnLoad="true"   trace="disable">
      <description/>
      <target>
         <inSequence>
            <xslt key="yourxsltkey"/> 
            <send/>
         </inSequence>
         <outSequence>
            <send/>
         </outSequence>
      </target>
</proxy>

where yourxsltkey is the key to your xslt definition. This can be either declare as local entry or in registry. As an sample here i have defined as a local entry.

<localEntry key="yourxsltkey">
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
        <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>

       <xsl:template match="/">
        <AAA xmlns="http://ws.apache.org/ns/synapse">
          <xsl:for-each select="AAA/BBB">
            <BBB><xsl:value-of select="CCC"/></BBB>
          </xsl:for-each>
        </AAA>
       </xsl:template>
    </xsl:stylesheet>

 </localEntry>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top