首页 > 代码库 > gSoap实现ONVIF中xsd__anyType到具体结构类的转换

gSoap实现ONVIF中xsd__anyType到具体结构类的转换

上一篇文章已经粗略计划要讨论gsoap关于序列化/解析编程。

本文则阐述一下关于gsoap生成代码的一些重要特征方法及使用。如题,下我们从ONVIF生成的C码中,挑选简单的一个类型来试验一下与xsd__anyType之间的转换。这个试验如此重要,主要是因为,在之前我真的拿生成代码的相关结构的的一些__any字段没有办法。虽依据ONVIF文档,以及实际交互观测的XML结构中可知明明是已知的标准结构,却无奈生成被解析成any字段,主要是可能这部分字段可由厂商决定填充哪些扩展意义的结构。

简单试验

本次试验选_trt__GetProfile结构作转换例程,主要理由是这个结构实在简单,只含有一个字段;书写初始化简单。

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

 

头部概览与FD操作

#include "inc.h"
typedef struct soap *soap_pointer;
#include "soap.nsmap"

// anyType
int 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;
}

注:inc.h是自组织的部分所需头依赖;

后面包含了soap.nsmap文件,你懂的,里面解开可以可以依次了解清楚包含与依赖关系;

soap.nsmap < soapH.h < soapStub.h < stdsoap2.h

主流程 main()

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 = http://www.mamicode.com/{"Profile0"};>

 

具体转换实现

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;
}

 

参考相关

gSOAP 2.8.11 User Guide

7.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 to

soap.sendfd = open(file, O_RDWR|O_CREAT, S_IWUSR|S_IRUSR);
soap_write_PointerTons_Person(&soap, &p);

gSoap生成代码的重要使用特征

 

gSoap实现ONVIF中xsd__anyType到具体结构类的转换