gSOAP:如何在响应中省略可选元素?

时间:2014-07-22 15:03:56

标签: c soap gsoap

我有一个SOAP函数,它在gSOAP语法中定义为

//gsoap ns service method-documentation: get foo and bar
int ns__getFooBar( xsd__string arg1, xsd__int arg2, struct ns__getFooBarResponse &response );

响应元素定义为

 //gsoap ns schema type-documentation: getFooBarResponse::foo Foo element, if available
 //gsoap ns schema type-documentation: getFooBarResponse::bar Bar element
 struct ns__getFooBarResponse { ns__FooType foo 0; ns__BarType bar; };

ns__getFooBarResponse的结果类型定义是:

#ifndef SOAP_TYPE_ns__getFooBarResponse
#define SOAP_TYPE_ns__getFooBarResponse (606)
/* ns:getcResponse */
struct ns__getFooBarResponse
{
public:
    ns__FooType foo;    /* SOAP 1.2 RPC return element (when namespace qualified) */    /* optional element of type ns:FooType */
    ns__BarType bar;    /* required element of type ns:BarType */
public:
    int soap_type() const { return 606; } /* = unique id SOAP_TYPE_ns__getFooBarResponse */
};
#endif

虽然foo被声明为可选,但它是ns__getFooBarResponse的普通类成员(对于可选成员,我猜想我会指望一个指针)。因此,foo始终存在(即使只是默认初始化),因此答案始终包含FooType元素。

如何提供仅包含所需BarType元素的响应,但省略了可选的FooType元素?

TL; DR

如何提供省略可选元素的gSOAP的SOAP响应?

修改

似乎问题部分不清楚:我不想完全摆脱我的应用程序的可选字段,但我想省略它可选如果函数调用仅提供信息BarType(取决于函数调用的参数)。这就是为什么它被定义为可选

WSDL:

<element name="getFooBarResponse">
 <complexType>
  <sequence>
   <element name="foo" type="ns:FooType" minOccurs="0" maxOccurs="1" />
   <element name="bar" type="ns:BarType" minOccurs="1" maxOccurs="1" />
  </sequence>
 </complexType>
</element>

2 个答案:

答案 0 :(得分:1)

正确的解决办法是让foo成为一个指针:

struct ns__getFooBarResponse { ns__FooType* foo 0; ns__BarType bar; };

这导致

struct hldc__getFooBarResponse 
{
public:
    ns__FooType *foo;   
    ns__BarType bar;    
public:
    int soap_type() const { return 55; } 
};

在我的代码中,我需要在需要时手动实例化FooType元素:

if( /* is foo data available for this response ?*/ ) 
    response.foo = soap_instantiate_ns__FooType( soap, -1, NULL, NULL, NULL );
    // fill foo with data
}

回复FooType

<ns:getFooBarResponse>
    <ns:FooType> <!--"foo" content --> </FooType>
    <ns:BarType> <!--"bar" content --> </ns:BarType>
</ns:getFooBarResponse>

没有FooType的回复:

<ns:getFooBarResponse>
    <ns:BarType> <!--"bar" content --> </ns:BarType>
</ns:getFooBarResponse>

答案 1 :(得分:0)

关于 如何使用省略可选元素的gSOAP提供SOAP响应?

我相信您可以通过 修改wsdl2h实用程序的.h文件输出

来实现此目的

使用gsoap实用程序wsdl2h.exe时,其输出为.h文件。

示例

c:\dev\gsoap\bin\win32\wsdl2h -c -o c:\dev\gsoapFiles\queries.h c:\dev\gsoapFiles\xyz.wsdl

这会生成queries.h。此文件永远不会在您的项目中用作源文件。相反,它只是用作gsoap实用工具soapcpp2.exe的输入。

示例

c:\dev\gsoap\bin\win32\soapcpp2 -C -c queries.h  

然而 ,在您以这种方式使用之前,编辑它以删除任何不需要的元素

我刚刚在几分钟前做过这件事并删除了3/4的文件内容。 .c文件输出大大简化,跳过了许多不必要的代码行的生成。

例如,我的应用程序不需要任何带有ns8 __...的东西,因此我使用该命名空间指示符删除了所有内容。如:

/// "http://www.sample.com/Alternates/1.0":AlternateParts is a complexType.
struct ns8__AlternateParts
{
/// Element User of type xs:string.
    char*                                User                           1;  ///< Required element.
/// Element ComponentName of type xs:string.
    char*                                ComponentName                  1;  ///< Required element.
/// Element reference "http://www.physio-control.com/Alternates/1.0":Alternates.
    struct _ns8__Alternates*             Alternates                     1;  ///< Required element.
}; 

对于结构,由于不需要一些成员,我删除了不必要的成员。如:

之前

/// "urn:sample-org:xxAutoTest:xxAutoTest":atsQueryResponse is a complexType.
struct ns10__atsQueryResponse
{
/// Element result of type xs:string.
    char*                                result                         0;  ///< Optional element.
    struct _ns10__atsQueryResponse_atsData
    {
/// Element atsSerial of type xs:string.
    char*                                atsSerial                      0;  ///< Optional element.
/// Element atsWrPart of type xs:string.
    char*                                atsWrPart                      0;  ///< Optional element.
/// Element atsWrStatus of type xs:string.
    char*                                atsWrStatus                    0;  ///< Optional element.
/// Element atsBomNumber of type xs:string.
    char*                                atsBomNumber                   0;  ///< Optional element.
/// Element atsRemanIdNum of type xs:string.
    char*                                atsRemanIdNum                  0;  ///< Optional element.
/// Element atsExpiryDate of type xs:string.
    char*                                atsExpiryDate                  0;  ///< Optional element.
/// Element atsStSerialUser50 of type xs:string.
    char*                                atsStSerialUser50              0;  ///< Optional element.
    }                                   *atsData                        0;  ///< Optional element.
/// Element opResult of type xs:string.
    char*                                opResult                       0;  ///< Optional element.
/// Element opDescription of type xs:string.
    char*                                opDescription                  0;  ///< Optional element.
}; 

之后

/// "urn:sample-org:xxAutoTest:xxAutoTest":atsQueryResponse is a complexType.
struct ns10__atsQueryResponse
{
/// Element result of type xs:string.
    char*                                result                         0;  ///< Optional element.
    struct _ns10__atsQueryResponse_atsData
    {
/// Element atsSerial of type xs:string.
    char*                                atsSerial                      0;  ///< Optional element.

    }                                   *atsData                        0;  ///< Optional element.
/// Element opResult of type xs:string.
    char*                                opResult                       0;  ///< Optional element.
/// Element opDescription of type xs:string.
    char*                                opDescription                  0;  ///< Optional element.
};