Consume a Web Service that returns an XML string

Consume a Web Service that returns an XML string

  
Hello,

I'm consuming a web service that is returning a string.
This output is in XML as the following (simplified) sample demonstrates:

<xml xmlns:s="uuid:..." xmlns:dt="." xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema">
<s:Schema id="RowsetSchema">
<s:ElementType name="row" content="eltOnly" rs:updatable="true">
    <s:AttributeType name="attribute1">
        <s:datatype dt:type="int" dt:maxLength="4" rs:precision="0" rs:fixedlength="true" rs:maybenull="false"/>
    </s:AttributeType>
    <s:AttributeType name="attribute2" rs:number="2" rs:nullable="true" rs:write="true">
        <s:datatype dt:type="string" rs:dbtype="str" dt:maxLength="4294967295" rs:precision="0" rs:long="true" rs:maybenull="false"/>
    </s:AttributeType>
...
</s:ElementType>
</s:Schema>
<rs:data>
    <z:row attribute1="1" attribute2="425/Tve"/>
    <z:row attribute1="2" attribute2="543/Tve"/>

    <z:row attribute1="3" attribute2="653/Tve"/>
    <z:row attribute1="4" attribute2="3/Tve"/>
</rs:data>
</xml>


Is there a way to automate its translation to a Service Studio structure, like Struture_Z with Attribute1 and Attribute2?

Thanks,
Pedro

Hi Pedro,

You want to automate the definition of the structure in Service Studio at design time, or the data conversion from XML to Service Studio structures in runtime?

Can you explain why exactly you need the automation?

Regards,

Daniel Lourenço
OutSystems

Hi Daniel,

Thanks for the reply.

I want to automate the data conversion from XML to Service Studio structures in runtime. I need this automation because my application will basically list and show this information as records. So I see 2 options (I look forward to hear more):

1. I pass this output through a translation logic which maps it into structures; this is very costly because I need to use the XML extension and work each piece of information (nodes and attributes) to an existing structure;

2. Same as the previous one; but using the XMLToRecordList action provided by XML extension; this would avoid creating the mapping logic... not sure it works, but I guess it's the best option available.

Any similar experiences?

Pedro


erm, don't understand. why not just add a webreference of that webservice, so service-studio will create the structures for you?




Hi Joost,

Thanks for your reply.

I wish I could. Unfortunately all the web services are designed to return a string, not a data set. This means that even if I can translate that info to structures I have to do it in runtime, not design time using Service Studio...

Cheers

sorry, I'm lost.

what do you mean by "a string" and not a dataset ?
a webservice always give a string back because it's human readable
then you parse it through, normally an xml-parser, so you can walk through it with xpath and such,
or use xml-2-recordlist to place it in a record-list





Here's a glimpse of the WSDL that defines the structures for each web service method:

    <s:element name="List">
        <s:complexType>
            <s:sequence>
                <s:element minOccurs="0" maxOccurs="1" name="EntidadeExternaID" type="s:string"/>
                <s:element minOccurs="0" maxOccurs="1" name="EntidadeInternaID" type="s:string"/>
                <s:element minOccurs="0" maxOccurs="1" name="ProcessoTipoID" type="s:string"/>
                <s:element minOccurs="0" maxOccurs="1" name="RepositorioID" type="s:string"/>
            </s:sequence>
        </s:complexType>
    </s:element>
    <s:element name="ListResponse">
        <s:complexType>
            <s:sequence>
                <s:element minOccurs="0" maxOccurs="1" name="ListResult" type="s:string"/>
            </s:sequence>
        </s:complexType>
    </s:element>
    <s:element name="ListDocuments">
        <s:complexType>
            <s:sequence>
                <s:element minOccurs="0" maxOccurs="1" name="ProcessID" type="s:string"/>
                <s:element minOccurs="0" maxOccurs="1" name="NomeCampoLivre" type="s:string"/>
                <s:element minOccurs="0" maxOccurs="1" name="ValorCampoLivre" type="s:string"/>
            </s:sequence>
        </s:complexType>
    </s:element>
    <s:element name="ListDocumentsResponse">
        <s:complexType>
            <s:sequence>
                <s:element minOccurs="0" maxOccurs="1" name="ListDocumentsResult" type="s:string"/>
            </s:sequence>
        </s:complexType>
    </s:element>
</s:schema>


All the Result elements highlighted above are string not an actual structure :( It's this string that contains XML...
Hi Joost and Pedro,

The XML extension Serialization_XmlToRecordList and Serialization_XmlToRecordList is purely a Serialization/Deserialization solution for OutSystems records. This means that you are able to convert an OutSystems record list to XML, and then convert that XML back to the OutSystems record list of the same type in runtime.

This solution uses a specific XML format for the object serialization - the goal is to be able to be able to "store" (i.e. serialize)  the status a record list (in a database, in a file, etc.) and then be able to convert it back to your application runtime list.

This XML format will surely not be the same as the one you need to parse, so I believe this is not the solution for you. I would not consider the option of converting your XML to the record list definition XML, because you would be dealing with the XML extension internal structures.

One option that I think you could consider is trying to figure out if you can create a "common" trunk in the several structures you will have to deal and try to create a "general" method for the serialization of the XML structures for that "common" structure.  As this would eliminate the strong typing of your different structures, I believe this would only be a good option if you have a great number of structures.

You could also do it other way - find a common part or structure in the processing logic of the XML. In the section where the processing differs from structure to structure, you could then call user actions that multiplex to the correct option for each structure.

Kind Regards,

Daniel Lourenço
OutSystems
(yes daniel, I knew that already )

Another option is to ask the provide if they fix the webservice so you can consume it on a normal way

Joost, I do not know if that is an option for Pedro, but, as a starting point, it is definitely the best idea I have seen in this thread :) .

It's funny that I'm having the exact same problem. I've asked the Web Service providers to change it, so it can be consumed directly from Service Studio and I'm still waiting for their feedback. If they say that's not an option I'de be interested in knowing if you found any solution that doesn't involve creating a custom extension to parse the XML and populate the structures.

Hi João,

Keep reading this topic. I guess it has helped some of us already ;)

By the way, you won't need to create a custom extension, I think. Besides what Daniel Lourenço referred in the post above, regarding the use of Xml extension to translate the string data into structures, you also have Xml Records extension which provides the same functionality through another approach. Thing is, I'm still trying to apply it to my case and so far no good :(

Cheers!
another suggestion to use xml extension daniel suggested and go from there.

why do you have to populate structures?
you want to keep them in your own database?
or when you changed stuff it goes back to the webservice?

if the latter, I would keep it in the xml, finding/replacing with the suggested extension.



I am having the same problem. Here is an example of an XML that I both send and receive. I send one out and it adds another question when it returns. I need to save the questions in the DB, and have the user provide answers through the application. It has a high level object (Questionnaire) and a list of related objects (Question). This result can only be sent and  returned as a cdata (string). I also need to construct the outgoing string with the list for invocation. I can create an empty Questionnaire from a query (no questions) but i need to construct and deconstruct the strings to and from the web service call.
Request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ques="http://questions.demo.fico.com/">
   <soapenv:Header/>
   <soapenv:Body>
      <ques:callMainExternal>
         <!--Optional:-->
         <arg0><![CDATA[<Questionnaire>
 <Id>1</Id>
 <QuestioningCompleted>false</QuestioningCompleted>
<Question>
  <Field>involvedAsDriverOrPassenger</Field>
  <Label>Where you involved as a driver or a passenger in the accident ?</Label>
  <DataType>boolean</DataType>
  <Value></Value>
 </Question></Questionnaire>]]></arg0>
      </ques:callMainExternal>
   </soapenv:Body>
</soapenv:Envelope>

Response:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
      <ns2:callMainExternalResponse xmlns:ns2="http://questions.demo.fico.com/">
         <return><![CDATA[<Questionnaire>
 <Id>1</Id>
 <QuestioningCompleted>false</QuestioningCompleted>
<Question>
  <Field>involvedAsDriverOrPassenger</Field>
  <Label>Where you involved as a driver or a passenger in the accident ?</Label>
  <DataType>boolean</DataType>
  <Value></Value>
 </Question><Question>
  <Field>involvedAsDriverOrPassenger</Field>
  <Label>Where you involved as a driver or a passenger in the accident ?</Label>
  <DataType>boolean</DataType>
  <Value></Value>
 </Question></Questionnaire>]]></return>
      </ns2:callMainExternalResponse>
   </soap:Body>
</soap:Envelope>