Navigation:  Advanced Topics > Web Services >

SOAP II - Processing the XML Response with XMLXPathReader

There is one more bit of work that needs to be done. Once the SOAP call has been made, we may want to parse the data into its components parts.

 

Lets take a quick look at the structure of the XML returned from our weather forecast.

 

<?xml version="1.0" encoding="utf-8"?>

<!-- Created with Liquid XML Studio - FREE Community Edition 7.1.6.1440 (http://www.liquid-technologies.com) -->

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

 <soap:Body>

         <GetCityForecastByZIPResponse xmlns="http://ws.cdyne.com/WeatherWS/">

                 <GetCityForecastByZIPResult>

                         <Success>true</Success>

                         <ResponseText>City Found</ResponseText>

                         <State>CA</State>

                         <City>Portola Valley</City>

                         <WeatherStationCity>Redwood City</WeatherStationCity>

                         <ForecastResult>

                                 <Forecast>

                                         <Date>1900-01-01T00:00:00</Date>

                                         <WeatherID>4</WeatherID>

                                         <Desciption>Sunny</Desciption>

                                         <Temperatures>

                                                 <MorningLow />

                                                 <DaytimeHigh>87</DaytimeHigh>

                                         </Temperatures>

                                         <ProbabilityOfPrecipiation>

                                                 <Nighttime />

                                                 <Daytime>00</Daytime>

                                         </ProbabilityOfPrecipiation>

                                 </Forecast>

                                 <Forecast>

                                         <Date>1900-01-01T00:00:00</Date>

                                         <WeatherID>4</WeatherID>

                                         <Desciption>Sunny</Desciption>

                                         <Temperatures>

                                                 <MorningLow>59</MorningLow>

                                                 <DaytimeHigh>85</DaytimeHigh>

                                         </Temperatures>

                                         <ProbabilityOfPrecipiation>

                                                 <Nighttime>00</Nighttime>

                                                 <Daytime>00</Daytime>

                                         </ProbabilityOfPrecipiation>

                                 </Forecast>

                                 ... more Forecast records here. 7 days worth in total.

 

Metadata

We have two metadata definitions ready to receive data from this XML Response data. We are not interested in all of the data and so we will set up the metadata fields we actually require. Note that I am being careful to name the Metadata fields exactly as the Web Service fields are named. This way, I do not need to explicitly map the XML to the metadata - Clover will do it for me.

 

Top level data : HdrIndexKey, Success, State and City.
7 days of forecast data : FIndexKey, Desciption (intentional misspelling as it is misspelt in the web service), Low, High

 

The reason we have the HdrIndexKey and FIndexKey fields is that we are going to ask Clover to generate Key sequence numbers for us that link the top level data with the7 days of forecast data. Strictly speaking, we would not need these in our example as we only get data from one City and so the 7 days of weather forecast data are always linked to that one city.

 

 

Graph

The graph shows how the XMLXPathReader will split the data up into 2 output ports. We would expect to get 1 row of top level data and 7 rows of forecast data.

 

ReadingFromPort

 

Mapping and Namespaces

In order to split the XML up, we need to do the mapping. This is a main property of the XMLXPathReader and this is how it looks.

 

<Context xpath="soap:Envelope/soap:Body/GetCityForecastByZIPResponse/GetCityForecastByZIPResult"

    outPort="0" sequenceField="HdrIndexKey"

    namespacePaths='"http://ws.cdyne.com/WeatherWS/";soap="http://www.w3.org/2003/05/soap-envelope"'>

  <Context xpath="ForecastResult/Forecast" parentKey="HdrIndexKey" generatedKey="FIndexKey"

         outPort="1">

         <Mapping xpath="Temperatures/MorningLow" cloverField="Low"/>

         <Mapping xpath="Temperatures/DaytimeHigh" cloverField="High"/>

  </Context>

</Context>

 

Yes, it is quite nasty looking. However, it is very logical. I will explain the things that we were not already covered in the earlier section.

 

You will notice that we have to explicitly address the Namespaces that are referenced in the Response XML.

 

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.

 

The line above references "soap" and "xsi". A few lines deeper into the XML we also have

 

<GetCityForecastByZIPResponse xmlns="http://ws.cdyne.com/WeatherWS/">

 

which is the default namespace for the main weather data.

 

We have to address these in the Mappings field and you can see the use of the namespacePaths attribute within the first <Context> element. Once we have specified the Namespace, we do not have to use them again for each nested <Context>.