Release 10.1A: OpenEdge Development:
Web Services

> ## DatatypeFormats sample walk-through

> `DatatypeFormats.p` follows these steps to prepare, call, and process the output from `MultiDatatypes( )` (source code edited and formatted for clarity):

> 1. Creates a Web service object in the 4GL:

>     DEFINE VARIABLE hWS AS HANDLE.
>     .
>     .
>     .
>     CREATE SERVER hWS.

> 2. Connects to the Web service (which has only one valid service and port):

>     hWS:CONNECT("-WSDL
>                   http://localhost/DatatypeFormats/Service1.asmx?WSDL).
>     IF NOT hws:CONNECTED() THEN
>     DO:
>         MESSAGE "SERVER:CONNECTED  :  " hws:CONNECTED() VIEW-AS ALERT-BOX.
>         LEAVE.
>     END.

> 3. Sets the handle to the port type in the WSDL where the `MultiDatatypes( )` operation is defined:

>     DEFINE VARIABLE hPortType AS HANDLE.
>     .
>     .
>     .
>     RUN Service1Soap SET hPortType ON SERVER hWS.
>     IF NOT VALID-HANDLE(hPortType) THEN
>     DO:
>         MESSAGE "hPortType valid: " VALID-HANDLE(hPortType)
>             VIEW-AS ALERT-BOX.
>         LEAVE.
>     END.

> 4. Creates the XML document used to pass the input complex type parameter as a `LONGCHAR`. This operation requires that the `INPUT` and `OUTPUT` parameters are XML documents because the Web service SOAP format is Document/Literal. The Web service expects the XML document input parameter to have this structure:

>     <ns0:MultiDatatypes xmlns:ns0="http://tempuri.org/">
>             <ns0:paramIn1>boolean-value</ns0:paramIn1>
>             <ns0:paramIn2>dateTime-value</ns0:paramIn2>
>             <ns0:paramIn3>duration-value</ns0:paramIn3>
>             <ns0:paramIn4>gDay-value</ns0:paramIn4>
>             <ns0:paramIn5>gMonth-value</ns0:paramIn5>
>             <ns0:paramIn6>gMonthDay-value</ns0:paramIn6>
>             <ns0:paramIn7>gYear-value</ns0:paramIn7>
>             <ns0:paramIn8>gYearMonth-value</ns0:paramIn8>
>     </ns0:MultiDatatypes>

> This is a sample of the code showing the `boolean` value of the first parameter and the `gYearMonth` value of the last parameter added to the newly-created XML document:

>     DEFINE VARIABLE lBoolIn as LOGICAL.
>     DEFINE VARIABLE sgYearMonthIn AS CHARACTER.
>     DEFINE VARIABLE hDoc AS HANDLE.
>     DEFINE VARIABLE hRoot AS HANDLE.
>     DEFINE VARIABLE hText AS HANDLE.
>     DEFINE VARIABLE hNode AS HANDLE.
>     DEFINE VARIABLE hChildNode AS HANDLE.
>     .
>     .
>     .
>     CREATE X-DOCUMENT hDoc.
>     CREATE X-NODEREF hRoot.
>     CREATE X-NODEREF hText.
>     CREATE X-NODEREF hNode.
>     CREATE X-NODEREF hChildNode.
>     hDoc:CREATE-NODE-NAMESPACE(hRoot, "http://tempuri.org/",
>                                "s0:MultiDatatypes", "element").
>     hRoot:SET-ATTRIBUTE("xmlns:s0", "http://tempuri.org/").
>     hDoc:APPEND-CHILD(hRoot).
>     /* paramIn1 boolean                                                  */
>     /* boolean value must one of the following values: true, false, 1, 0 */
>     lBoolIn = TRUE.
>     hDoc:CREATE-NODE-NAMESPACE(hNode, "http://tempuri.org/",
>                                "s0:paramIn1", "element").
>     hRoot:APPEND-CHILD(hNode).
>     hDoc:CREATE-NODE(hText, ?, "text").
>     hText:NODE-VALUE = STRING(lBoolIn, "true/false").
>     hNode:APPEND-CHILD(hText).
>     .
>     .
>     .
>     /* paramIn8 gYearMonth                        */
>     /* dYearMonth must be in the format "YYYY-MM" */
>     sgYearMonthIn = "199902".
>     hDoc:CREATE-NODE-NAMESPACE(hNode, "http://tempuri.org/",
>                                "s0:paramIn8", "element").
>     hRoot:APPEND-CHILD(hNode).
>     hDoc:CREATE-NODE(hText, ?, "text").
>     hText:NODE-VALUE = STRING(sgYearMonthIn, "9999-99").
>     hNode:APPEND-CHILD(hText).

> 5. Saves the XML document `INPUT` parameter as a `LONGCHAR`:

>     DEFINE VARIABLE ret AS LOGICAL.
>     DEFINE VARIABLE lcInput AS LONGCHAR VIEW-AS EDITOR LARGE SIZE 40 BY 10.
>     .
>     .
>     .
>     ret = hDoc:SAVE( "longchar" , lcInput).

> 6. Invokes the `MultiDatatypes( )` operation of the Web service by making a procedure call:

>     DEFINE VARIABLE lcOutput AS LONGCHAR VIEW-AS EDITOR LARGE SIZE 70 BY 10.
>     .
>     .
>     .
>     IF ret THEN
>     DO:
>       RUN MultiDatatypes IN hPortType (INPUT lcInput, OUTPUT lcOutput)
>           NO-ERROR.
>     .
>     .
>     .
>     END.

> 7. Checks for errors and manages the information for any that occur (see the "Common procedure for SOAP fault handling" section):

>     DEFINE VARIABLE err AS LOGICAL.
>     .
>     .
>     .
>     ON CHOOSE of bgetQuote
>     DO:
>       .
>       .
>       .
>       RUN MultiDatatypes IN hPortType (INPUT lcInput, OUTPUT lcOutput)
>           NO-ERROR.
>       RUN ErrorInfo (OUTPUT err).
>      .
>      .
>      .

> 8. If there are no errors, loads the XML document that was passed back in the `OUTPUT` parameter:

>     DO:
>     .
>     .
>     .
>       IF NOT err THEN
>       DO:
>         ret = hDoc:LOAD("longchar" , lcOutput, FALSE).
>     .
>     .
>     .
>       END.
>     END.

> The Web service returns the output XML document with the following structure:

>     <ns0:MultiDatatypesResponse xmlns:ns0="http://tempuri.org/">
>             <ns0:paramOut1>boolean-value</ns0:paramOut1>
>             <ns0:paramOut2>dateTime-value</ns0:paramOut2>
>             <ns0:paramOut3>duration-value</ns0:paramOut3>
>             <ns0:paramOut4>gDay-value</ns0:paramOut4>
>             <ns0:paramOut5>gMonth-value</ns0:paramOut5>
>             <ns0:paramOut6>gMonthDay-value</ns0:paramOut6>
>             <ns0:paramOut7>gYear-value</ns0:paramOut7>
>             <ns0:paramOut8>gYearMonth-value</ns0:paramOut8>
>     </ns0:MultiDatatypesResponse>

> 9. Parses the XML document, with the following code showing how values are retrieved for the `boolean` value of the first parameter and the `gYearMonth` value of the last parameter of the complex type:

>     DO:
>     .
>     .
>     .
>       DO:
>         .
>         .
>         .
>         hDoc:GET-DOCUMENT-ELEMENT(hRoot).
>         DO i = 1 TO hRoot:NUM-CHILDREN:
>           hRoot:GET-CHILD(hNode, i).
>           IF hNode:SUBTYPE = "ELEMENT" THEN
>           DO:
>               IF hNode:NAME = "paramOut1" THEN /* boolean */
>               DO:
>                   Ret = hNode:GET-CHILD(hChildNode, 1).
>                   IF ret AND hChildNode:subtype = "TEXT" THEN
>                      BoolOut = LOGICAL(hChildNode:NODE-VALUE).
>               END.
>               .
>               .
>               .
>               IF hNode:NAME = "paramOut8" THEN /* gYearMonth */
>               DO:
>                   Ret = hNode:GET-CHILD(hChildNode, 1).
>                   IF ret AND hChildNode:subtype = "TEXT" THEN
>                      sgYearMonthOut = hChildNode:NODE-VALUE.
>               END.
>           END.
>         END.
>         .
>         .
>         .
>       END.
>     END.

> 10. Displays the data that was extracted from the XML:

>     DO:
>       .
>       .
>       .
>       DO:
>          .
>          .
>          .
>         MESSAGE "Return Values = " SKIP
>            lBoolOut SKIP
>            dtzDateOut SKIP
>            sdurationOut SKIP
>            sgDayOut SKIP
>            sgMonthOut SKIP
>            sgMonthDayOut SKIP
>            sgYearOut SKIP
>            sgYearMonthOut
>         VIEW-AS ALERT-BOX.
>       END.
>     END.

> 11. Cleans up by running this code:

>     DELETE PROCEDURE hPortType.
>     hWS:DISCONNECT().
>     DELETE OBJECT hWS.

> Which:

> 1. Deletes the procedure object.
> 2. Disconnects from the Web service.
> 3. Deletes the Web service object.

Copyright © 2005 Progress Software Corporation www.progress.com Voice: (781) 280-4000 Fax: (781) 280-4095