The previous article has roughly planned to discuss gsoap's serialization/parsing programming.
This article describes some important feature methods and usage of gsoap code generation. For example, select a simple type from the C code generated by onvif to test the conversion from XSD _ anytype. This experiment is so important mainly because I had no way to take some _ Any fields in the relevant structure of the generated code. Although the XML structure based on the onvif document and the actual interactive observation shows that it is a known standard structure, it is helpless to generate an any field, it is possible that the vendor determines the extended structure of the field.
Simple Test
In this test, the _ TRT _ getprofile structure is selected as the conversion routine. The main reason is that the structure is simple and contains only one field. The writing Initialization is simple.
Struct _ TRT _ getprofile
# Soapstub. h
#ifndef SOAP_TYPE__trt__GetProfile#define SOAP_TYPE__trt__GetProfile (1365)/* trt:GetProfile */struct _trt__GetProfile{char *ProfileToken;/* required element of type tt:ReferenceToken */};#endif
Head overview and FD operations
#include "inc.h"typedef struct soap *soap_pointer;#include "soap.nsmap"// anyTypeint anyType_ready(void){return open("anyType.xml", O_RDWR|O_CREAT, S_IWUSR|S_IRUSR);}int FD_set(int* FD, int fd){int ret = *FD; *FD = fd;return ret;}
Note: Inc. H is the header dependency required for self-organizing;
The soap. nsmap file is included later. You know, you can understand the inclusion and dependency in sequence by undoing it;
Soap. nsmap <soaph. H <soapstub. H <stdsoap2.h
Main Process ()
static xsd__anyType* _trt__GetProfile2anyType(soap_pointer soap_, struct _trt__GetProfile* p_, xsd__anyType* _any);static struct _trt__GetProfile*_trt__GetProfile_from_anyType(soap_pointer soap_, struct _trt__GetProfile* _p, xsd__anyType* _any);int main(int argc, char const *argv[]){/* code */struct soap soap;soap_pointer soap_ = &soap;soap_init(soap_);struct _trt__GetProfile Data = {"Profile0"};xsd__anyType Dom; soap_default_xsd__anyType(soap_, &Dom);if (_trt__GetProfile2anyType(soap_, &Data, &Dom)){soap_default__trt__GetProfile(soap_, &Data);if (_trt__GetProfile_from_anyType(soap_, &Data, &Dom))printf("Data >%s", Data.ProfileToken);}soap_end(soap_);soap_done(soap_);return 0;}
Specific conversion implementation
xsd__anyType* _trt__GetProfile2anyType( soap_pointer soap_, struct _trt__GetProfile* p_, xsd__anyType* _any ){int fd = anyType_ready();bool b = (fd == -1);if (b) return NULL;do {int* FD = &(soap_->sendfd);fd = FD_set(FD, fd);b = (soap_write__trt__GetProfile(soap_, p_) != SOAP_OK);fd = FD_set(FD, fd);b &= (lseek(fd, 0, SEEK_SET) == -1);if (b) break;FD = &(soap_->recvfd);fd = FD_set(FD, fd);b = (soap_read_xsd__anyType(soap_, _any) != SOAP_OK);fd = FD_set(FD, fd);} while(false);close(fd);if (b) return NULL;return _any;}struct _trt__GetProfile* _trt__GetProfile_from_anyType(soap_pointer soap_,struct _trt__GetProfile* _p, xsd__anyType* _any){int fd = anyType_ready();bool b = (fd == -1);if (b) return NULL;do {int* FD = &(soap_->sendfd);fd = FD_set(FD, fd);b = (soap_write_xsd__anyType(soap_, _any) != SOAP_OK);fd = FD_set(FD, fd);b &= (lseek(fd, 0, SEEK_SET) == -1);if (b) break;FD = &(soap_->recvfd);fd = FD_set(FD, fd);b = (soap_read__trt__GetProfile(soap_, _p) != SOAP_OK);fd = FD_set(FD, fd);} while(false);close(fd);if (b) return NULL;return _p;}
See gsoap 2.8.11 user guide7.5.3 serializing C/C ++ data to XML
You can assign an output stream to soap. OS or a le descriptor to soap. sendfd. For example
soap.sendfd = open(file, O_RDWR|O_CREAT, S_IWUSR|S_IRUSR);soap_serialize_PointerTons_Person(&soap, &p);soap_begin_send(&soap);soap_put_PointerTons_Person(&soap, &p, "ns:element-name", "ns:type-name");soap_end_send(&soap);
The above can be abbreviated
soap.sendfd = open(file, O_RDWR|O_CREAT, S_IWUSR|S_IRUSR);soap_write_PointerTons_Person(&soap, &p);
Important usage features of gsoap code generation
Gsoap converts XSD _ anytype in onvif to a specific structural class