0
votes

I´m working in a scenario with a proxy service that call a dataservice and send it this message:

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:add="http://www.example.org/Address/">
   <soap:Body>
      <dat:getmpartybranch xmlns:dat="http://ws.wso2.org/dataservice">
         <dat:clientid>473906852857651</dat:clientid>
      </dat:getmpartybranch>
   </soap:Body>
</soap:Envelope>

And recieve this response:

<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
   <soapenv:Header></soapenv:Header>
   <soapenv:Body>
      <DataCollection xmlns="http://ws.wso2.org/dataservice">
         <Datalist>
            <partybranchid>796243010946586</partybranchid>
            <clientid>473906852857651</clientid>
         </Datalist>
         <Datalist>
            <partybranchid>2500000000</partybranchid>
            <clientid>473906852857651</clientid>
         </Datalist>
      </DataCollection>
   </soapenv:Body>
</soapenv:Envelope>

The proxy iterate over each Datalist node, and with the values of clientid and partybranchid, it create another request a send to a another dataservice:

request1:

<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
   <soapenv:Body>
      <dat:getselect_addresses xmlns:dat="http://ws.wso2.org/dataservice">
         <dat:objectid>796243010946586</dat:objectid>
         <dat:clientid>473906852857651</dat:clientid>
      </dat:getselect_addresses>
   </soapenv:Body>
</soapenv:Envelope>

request2:

<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
   <soapenv:Body>
      <dat:getselect_addresses xmlns:dat="http://ws.wso2.org/dataservice">
         <dat:objectid>2500000000</dat:objectid>
         <dat:clientid>473906852857651</dat:clientid>
      </dat:getselect_addresses>
   </soapenv:Body>
</soapenv:Envelope>

response1:

<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
   <soapenv:Header></soapenv:Header>
   <soapenv:Body>
      <Addresses xmlns="http://ws.wso2.org/dataservice">
         <Address>
            <address>direccion1</address>
            <partybranchid>796243010946586</partybranchid>
            <clientid>473906852857651</clientid>
         </Address>
         <Address>
            <address>direccion3</address>
            <partybranchid>796243010946586</partybranchid>
            <clientid>473906852857651</clientid>
         </Address>
      </Addresses>
   </soapenv:Body>
</soapenv:Envelope>

response2:

<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
   <soapenv:Header></soapenv:Header>
   <soapenv:Body>
      <Addresses xmlns="http://ws.wso2.org/dataservice">
         <Address>
            <address>yo</address>
            <partybranchid>2500000000</partybranchid>
            <clientid>473906852857651</clientid>
         </Address>
      </Addresses>
   </soapenv:Body>
</soapenv:Envelope>

In the outsequece I use a agregator mediator with this expression //add:Addresses/add:Address, so my out put message look like this:

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
    <soapenv:Body>
        <Address xmlns="http://ws.wso2.org/dataservice"><address>direccion1</address><partybranchid>796243010946586</partybranchid><clientid>473906852857651</clientid></Address>
        <Address xmlns="http://ws.wso2.org/dataservice"><address>direccion3</address><partybranchid>796243010946586</partybranchid><clientid>473906852857651</clientid></Address>
        <Address xmlns="http://ws.wso2.org/dataservice"><address>yo</address><partybranchid>2500000000</partybranchid><clientid>473906852857651</clientid></Address>
    </soapenv:Body>
</soapenv:Envelope>

The output sequence:

  <outSequence>
     <aggregate id="iterate1">
        <completeCondition>
           <messageCount min="-1" max="-1"/>
        </completeCondition>
        <onComplete xmlns:s12="http://www.w3.org/2003/05/soap-envelope"
                    xmlns:add="http://ws.wso2.org/dataservice"
                    xmlns:s11="http://schemas.xmlsoap.org/soap/envelope/"
                    expression="//add:Addresses/add:Address">
           <log level="full"/>
        </onComplete>
     </aggregate>
     <xslt key="conf:/xslt/Tranformacion_DS_to_ESB.xsl"/>
     <send/>
  </outSequence>

Now I want to transform this message with XSLT so I use ALTOVA XML SPY and build this "Tranformacion_DS_to_ESB.xsl":

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:a="http://ws.wso2.org/dataservice" xmlns:b="http://www.example.org/Address/" exclude-result-prefixes="a fn xs">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:template match="/">
        <b:getAddressResponse>
            <xsl:for-each select="//a:Address">
                    <address>
                        <address>
                            <xsl:value-of select="a:address"/>
                        </address>
                        <partybranchid>
                            <xsl:value-of select="a:partybranchid"/>
                        </partybranchid>
                        <clientid>
                            <xsl:value-of select="a:clientid"/>
                        </clientid>
                    </address>
            </xsl:for-each>
        </b:getAddressResponse>
    </xsl:template>
</xsl:stylesheet>

If I test this transform in XML SPY with the previous soap message the result is this:

<?xml version="1.0" encoding="UTF-8"?>
<b:getAddressResponse xmlns:b="http://www.example.org/Address/">
    <address>
        <address>direccion1</address>
        <partybranchid>796243010946586</partybranchid>
        <clientid>473906852857651</clientid>
    </address>
    <address>
        <address>direccion3</address>
        <partybranchid>796243010946586</partybranchid>
        <clientid>473906852857651</clientid>
    </address>
    <address>
        <address>yo</address>
        <partybranchid>2500000000</partybranchid>
        <clientid>473906852857651</clientid>
    </address>
</b:getAddressResponse>

And it´s OK, but when I put this transformation inside the ESB after the aggregate mediator finish it work I recieve this wrong message:

<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
   <soapenv:Body>
      <b:getAddressResponse xmlns:b="http://www.example.org/Address/">
         <address>
            <address>direccion1</address>
            <partybranchid>796243010946586</partybranchid>
            <clientid>473906852857651</clientid>
         </address>
      </b:getAddressResponse>
      <Address xmlns="http://ws.wso2.org/dataservice">
         <address>direccion3</address>
         <partybranchid>796243010946586</partybranchid>
         <clientid>473906852857651</clientid>
      </Address>
      <Address xmlns="http://ws.wso2.org/dataservice">
         <address>yo</address>
         <partybranchid>2500000000</partybranchid>
         <clientid>473906852857651</clientid>
      </Address>
   </soapenv:Body>
</soapenv:Envelope>

Any idea about this result??

EDIT: When I try the code suggested by matthias I get a correct output in XML SPY but in ESB I get another wrong output:

<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
   <soapenv:Body>
      <address xmlns:b="http://www.example.org/Address/">
         <address>direccion1</address>
         <partybranchid>796243010946586</partybranchid>
         <clientid>473906852857651</clientid>
      </address>
      <Address xmlns="http://ws.wso2.org/dataservice">
         <address>direccion3</address>
         <partybranchid>796243010946586</partybranchid>
         <clientid>473906852857651</clientid>
      </Address>
      <Address xmlns="http://ws.wso2.org/dataservice">
         <address>yo</address>
         <partybranchid>2500000000</partybranchid>
         <clientid>473906852857651</clientid>
      </Address>
   </soapenv:Body>
</soapenv:Envelope>

LAST UPDATE: Using what @Ratha suggest me and this link wso2 ESB : Split / Gather Pattern - Single Response this is the right config.

This is my outsequence:

  <outSequence>
     <property name="root" scope="default">
        <root:rootelement xmlns:root="http://ws.wso2.org/dataservice"/>
     </property>
     <aggregate id="iterate1">
        <completeCondition>
           <messageCount min="-1" max="-1"/>
        </completeCondition>
        <onComplete xmlns:s12="http://www.w3.org/2003/05/soap-envelope"
                    xmlns:add="http://ws.wso2.org/dataservice"
                    xmlns:s11="http://schemas.xmlsoap.org/soap/envelope/"
                    expression="//add:Addresses/add:Address"
                    enclosingElementProperty="root">
           <log level="full"/>
        </onComplete>
     </aggregate>
     <xslt key="conf:/xslt/Tranformacion_DS_to_ESB.xsl"/>
     <send/>
  </outSequence>

As you can see I put a root property with rootelement as the root for my aggregated messages and use the enclosingElementProperty="root" inside the onComplete config, so my aggregate output look like this now:

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
    <soapenv:Body>
        <root:rootelement xmlns:root="http://ws.wso2.org/dataservice">
            <Address xmlns="http://ws.wso2.org/dataservice">
                <address>direccion1</address>
                <partybranchid>796243010946586</partybranchid>
                <clientid>473906852857651</clientid>
            </Address>
            <Address xmlns="http://ws.wso2.org/dataservice">
                <address>direccion3</address>
                <partybranchid>796243010946586</partybranchid>
                <clientid>473906852857651</clientid>
            </Address>
            <Address xmlns="http://ws.wso2.org/dataservice">
                <address>yo</address>
                <partybranchid>2500000000</partybranchid>
                <clientid>473906852857651</clientid>
            </Address>
        </root:rootelement>
    </soapenv:Body>
</soapenv:Envelope>

And I update my XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:a="http://ws.wso2.org/dataservice" xmlns:b="http://www.example.org/Address/" exclude-result-prefixes="a fn xs">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:template match="/">
        <b:getAddressResponse>
            <xsl:for-each select="//a:rootelement/a:Address">
                    <address>
                        <address>
                            <xsl:value-of select="a:address"/>
                        </address>
                        <partybranchid>
                            <xsl:value-of select="a:partybranchid"/>
                        </partybranchid>
                        <clientid>
                            <xsl:value-of select="a:clientid"/>
                        </clientid>
                    </address>
            </xsl:for-each>
        </b:getAddressResponse>
    </xsl:template>
</xsl:stylesheet>

Now my proxy response is this, as I want:

<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
   <soapenv:Body>
      <b:getAddressResponse xmlns:b="http://www.example.org/Address/">
         <address>
            <address>direccion1</address>
            <partybranchid>796243010946586</partybranchid>
            <clientid>473906852857651</clientid>
         </address>
         <address>
            <address>direccion3</address>
            <partybranchid>796243010946586</partybranchid>
            <clientid>473906852857651</clientid>
         </address>
         <address>
            <address>yo</address>
            <partybranchid>2500000000</partybranchid>
            <clientid>473906852857651</clientid>
         </address>
      </b:getAddressResponse>
   </soapenv:Body>
</soapenv:Envelope>
1
About the configuration / envelope issue I just found another SO post mentioning this kind of problem and offering an approach. Not sure if applyable but just wanted to share in case this could be of any help: stackoverflow.com/questions/17903010/…matthias_h
thanks, I will try this approach and come back with the resultsJorge Infante Osorio
@JorgeInfanteOsorio log the output of the aggregate mediator after the aggregate mediator ends. Just before sending to xslt mediator and see the logged message's format. Then you can easily identify the issueRatha
@Ratha the output is in my post and it´s OK, I used it to test with the XMLSPY and the XSL result is fine, the problem is ESB related.Jorge Infante Osorio
@JorgeInfanteOsorio i posted answer.Please checkRatha

1 Answers

1
votes

Issue here is, your request for the XSLT mediator does not have root element. That is, within soap body, all three <Address> elemnts are in same level. They do not have root elemnt for them. When esb sends the message to xslt it will pass the body message. Here xslt will pick only the very first <Address> element and transform. To overcome, make your soap body with a wrapping root element. For example:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://services.samples" xmlns:xsd="http://services.samples/xsd">
   <soapenv:Header/>
   <soapenv:Body>
  <root xmlns="http://ws.wso2.org/dataservice">
     <Address xmlns="http://ws.wso2.org/dataservice">
        <address>direccion1</address>
        <partybranchid>796243010946586</partybranchid>
        <clientid>473906852857651</clientid>
     </Address>
        <Address xmlns="http://ws.wso2.org/dataservice">
            <address>direccion3</address>
            <partybranchid>796243010946586</partybranchid>
            <clientid>473906852857651</clientid>
        </Address>
        <Address xmlns="http://ws.wso2.org/dataservice">
            <address>yo</address>
            <partybranchid>2500000000</partybranchid>
            <clientid>473906852857651</clientid>
        </Address>
        </root>
   </soapenv:Body>
</soapenv:Envelope>

If you send like that you will get output like this;

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsd="http://services.samples/xsd" xmlns:ser="http://services.samples">
    <soapenv:Body>
        <b:getAddressResponse xmlns:b="http://www.example.org/Address/">
            <address>
                <address></address>
                <partybranchid></partybranchid>
                <clientid></clientid>
            </address>
            <address>
                <address></address>
                <partybranchid></partybranchid>
                <clientid></clientid>
            </address>
            <address>
                <address></address>
                <partybranchid></partybranchid>
                <clientid></clientid>
            </address>
        </b:getAddressResponse>
    </soapenv:Body>
</soapenv:Envelope>

Note: Edit your xslt with the right xpath .