Sunday, July 24, 2016

[WSO2 ESB] Saving a XML payload as a property and applying XPATH expressions.

Assume that you need to retrieve some values from a XML payload using a XPATH expression.
Let’s assume that this is the payload you are getting from the service (Proxy service or API) you invoke from WSO2 ESB. And you need to retrieve the userId of a particular person when you give the name of that person.

<Entries>
                 <Entry>
                    <name>Olivia</name>
                    <userId>1</userId>
                 </Entry>
                 <Entry>
                    <name>Abby</name>
                    <userId>2</userId>
                 </Entry>
                 <Entry>
                    <name>Bella</name>
                    <userId>3</userId>
                 </Entry>
                 <Entry>
                    <name>Hannah</name>
                    <userId>4</userId>
                 </Entry>
                 <Entry>
                    <name>Sabrina</name>
                    <userId>5</userId>
                 </Entry>
              </Entries>


ESB has property type called “OM” to save property values in message context as XML. This is useful when the expressions we write are associated with XML. For example if we want to write a XPATH expression by referring a property, that property has to be a XML object.  

This is the way of saving the above payload with the data type ‘OM’.

<property name="entries" expression="//Entries" type="OM"/>

Here is the proxy service.

<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="test" transports="https,http" statistics="disable" trace="disable" startOnLoad="true">
   <target>
      <inSequence>
         <call>
            <endpoint key="EP" />
         </call>
         <property name="entries" expression="//Entries" type="OM" />
         <property name="userId" expression="$ctx:entries//Entry/name[text()='Bella']//following-sibling::*[1]/text()" />
         <log level="custom">
            <property name="userId" expression="get-property('userId')" />
         </log>
      </inSequence>
   </target>
   <description />
</proxy>
                               
                            
I have created an endpoint in ESB named ‘EP’ which returns the above mentioned payload.

 <property name="userId"
   expression="$ctx:entries//Entry/name[text()='Bella’]//following-sibling::*[1]/text()"/>

From this property we can retrieve the userId element which is the following sibling of the name element which has the value ‘Bella’.

From the log mediator this will return the value as 3.



If we want to pass the name as a parameter without hard coding it in the XPATH expression we can define the property like this.

 <property name="userId"     expression="$ctx:entries//Entry/name[text()=$ctx:nameOfThePerson]//following-sibling::*[1]/text()"/>

In here message context must have a property named ‘nameOfThePerson’. We can define a property with the value of the name we want to retrieve and keep it in the message context. Then we can refer the message context and use it in XPATH expression.

You don’t need to save the payload as this if you want to get the values of elements just after receiving the payload(Just after calling the endpoint). You can simply write the XPATH expression to retrieve those values. This method is useful when you want to refer the payload after a while in your sequence or API or proxy service when the message context does not contain the received payload.


2 comments:

  1. hi Bashinee, could you plz tell how to extract only userid and log it

    ReplyDelete
  2. tried using iterator but the response got is concatenated.

    ReplyDelete