Subscribe for automatic updates: RSS icon RSS

Login icon Sign in for full access | Help icon Help
Advanced search

Pages: [1]
  Reply  |  Print  
Author Topic: Writing a web service that can receive an XML document  (Read 28231 times)
Rob K.
Posts: 3


« on: July 28, 2012, 11:42:24 am »

Hi
As I am new to Web services and Genero too, I am struggling with a concept. Can one write a web service that can receive an entire XML document. I have a need to receive a lab result in an xml document into my service and parse it out and extract the relevant data.

I have written a few web services that use simpler data types and return records and arrays, but nothing that can take a whole document. When I make a server that starts like this:
IMPORT com
#
# USER GLOBALS VARIABLES
#

GLOBALS
DEFINE
   record_in record
      doc   om.DomDocument
   end record,
   record_out record
      responded record
         reply_i   integer,
         reply_c char(3)
      end record
   end record,
   ch base.Channel
END GLOBALS
the fglwsdl tool generates code for a client, but the .inc file then defines
TYPE tread_docRequest_read_docRequest RECORD ATTRIBUTE(XMLSequence,XSTypeName="read_docReq
uest_read_docRequest",XSTypeNamespace="http://tempuri.org/")
  doc xml.DomDocument ATTRIBUTE(XMLName="doc")
| The symbol 'xml' does not represent a valid variable type.
| See error number -6622.
END RECORD

with "doc xml.DomDocument", which the compiler throws an error on, at which point I am stuck ....


I unfortunately find the genero documentation very terse, and there is not much by way of example, and I have been unable to find much on the internet that looks like what I am trying to do.

Can someone out there point me in the right direction.
Reuben B.
Four Js
Posts: 1116


« Reply #1 on: July 30, 2012, 01:32:53 am »

...
 doc xml.DomDocument ATTRIBUTE(XMLName="doc")
| The symbol 'xml' does not represent a valid variable type.
| See error number -6622.

...

... that error occurs if you are missing the IMPORT xml at the top of the code.  In your sample you have IMPORT com, but no IMPORT xml.  Add IMPORT xml.

Two bits of historical information ...

1.  Originally the Web Service extensions was a separate add-on that you installed on top of the base Genero product.  It consisted of the two classes, the Com Library https://4js.com/online_documentation/fjs-gws-manual-html/User/WseCOMLibrary.html and the XML Library https://4js.com/online_documentation/fjs-gws-manual-html/User/WseXMLLibrary.html.  A few releases ago it was decided to incorporate the Web Services extension into the standard package.  To utilise the two classes you still need to use the IMPORT statement.  This is similar to the File Manipulation https://4js.com/online_documentation/fjs-fgl-manual-html/User/Ext_os_Path.html and Maths classes https://4js.com/online_documentation/fjs-fgl-manual-html/User/Ext_util_Math.html where you also need to use the IMPORT statement.  The built-in classes, base, ui, om, you don't need the IMPORT statement.

2. I noticed you used the om.DomDocument type.  The om classes have been in Genero right from the beginning and were primarily used for manipulating the XML document associated with the Abstract User Interface.  Genero developers who did their migrations 10 years ago didn't have methods such as ui.Form.setFieldHidden() and wrote their own functions using the om classes to manipulate the AUI Tree.  Functionality in the om classes is a reduced set of functionality when compared to what is in the Web Services xml library as it was intended to help manipulate the AUI Tree rather than being a full blown XML library.   My rule of thumb is if dealing with AUI Tree use om.DomDocument, if dealing with XML Documents, use xml.DomDocument.

Product Consultant (Asia Pacific)
Developer Relations Manager (Worldwide)
Author of https://4js.com/ask-reuben
Contributor to https://github.com/FourjsGenero
Rob K.
Posts: 3


« Reply #2 on: August 03, 2012, 05:42:22 pm »

Indeed, I had left that out. Silly mistake. I have added in and all compiles.

I now via the client to the server thus:

LET d = xml.DomDocument.create()
call d.load("LABRES.xml")
LET r = d.getDocumentElement()
display r.toString() #confirms has been read

#set the global = to the local variable ?
let read_docRequest.doc = d

call read_doc_g()
   returning ws_status


where read_docRequest.doc is the 'receiving' variable on the server side, also defined as xml.DomDocument
record_in record
      doc   xml.DomDocument
end record,


With the server listening, the client returns with error : Error: Object 'doc': unexpected node

Clearly I am missing the obvious, but see nothing in either the documentation nor find and explanation or example online. Is there somewhere online where I can find some sort of simple example of this sort of function or am I hoping for too much ?
Rob K.
Posts: 3


« Reply #3 on: August 03, 2012, 05:54:07 pm »

Whoops : that error shows up in the CLIENT error-log
Program error at 'wsxmlCf.4gl', line number 85.
FORMS statement error number -15631.
Serializer runtime exception : Object 'doc': unexpected node.

on a line of
85   CALL xml.Serializer.VariableToStax(read_docRequest,writer)

I am missing more than I thought
Reuben B.
Four Js
Posts: 1116


« Reply #4 on: August 04, 2012, 12:07:05 am »

Hi Rob,

One of my clients had a similar requirement a few years ago.  They implemented it at the time by serializing the XML document as a STRING so that the web service function was 1 STRING in and 1 STRING out.

I tried at the time to create an example similar to my RESTful Web Services example http://code.google.com/p/sourcefourjs/downloads/detail?name=calcrest_1_0.zip
where I took the Calculator demo found in FGLDIR/demo/WebServices/Calculator and modified it to be RESTful rather than SOAP.  I was trying to take the Calculator example and modify it to be 1 xml.DomDocument in and 1 xml.DomDocument out.  I suspect I ran into similar issues you are running into now.

I revisited this example during the week and have moved it forward.  I have attached my example as it stands.  The step I was missing was to use DocStyle and not RPC, and to add the following attributes to my record ...

Code
  1.  DEFINE
  2.    dom_in RECORD
  3.        document xml.DomDocument ATTRIBUTE(XMLAny, XMLNamespace="##any")
  4.    END RECORD,
  5.    dom_out RECORD
  6.        document xml.DomDocument ATTRIBUTE(XMLAny, XMLNamespace="##any")
  7.    END RECORD

... what I aren't happy with is in the client I end up the record element being called _ANY_0 instead of "document"

Code
  1. LET root_req = DomRequest._ANY_0.getDocumentElement()

I'd rather that had the name I gave it in the server.

Hope that helps

Reuben

* calcdom.zip (24.21 KB - downloaded 1437 times.)

Product Consultant (Asia Pacific)
Developer Relations Manager (Worldwide)
Author of https://4js.com/ask-reuben
Contributor to https://github.com/FourjsGenero
Reuben B.
Four Js
Posts: 1116


« Reply #5 on: August 08, 2012, 06:06:49 am »

Hi Rob,

I tweaked my example program and have put it up on sourcefourjs with the filename calcdom_1_0.zip.  You can download from http://code.google.com/p/sourcefourjs/downloads/list.

The record definition is now ...

Code
  1.  DEFINE
  2.    dom_in RECORD ATTRIBUTE(XMLName="dom_in", XMLNamespace="http://tempuri.org")
  3.        document xml.DomDocument ATTRIBUTE(XMLName="document")
  4.  
  5.    END RECORD,
  6.    dom_out RECORD ATTRIBUTE(XMLName="dom_out", XMLNamespace="http://tempuri.org")
  7.        document xml.DomDocument ATTRIBUTE(XMLName="document")
  8.    END RECORD

... and IMHO results in neater code on the server and the client.

Reuben   

Product Consultant (Asia Pacific)
Developer Relations Manager (Worldwide)
Author of https://4js.com/ask-reuben
Contributor to https://github.com/FourjsGenero
Pages: [1]
  Reply  |  Print  
 
Jump to:  

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines