gSOAP和ONVIF NVT命名空间/标签问题

时间:2016-08-24 16:02:49

标签: c++ gsoap onvif

我正在尝试使用gsoap实现ONVIF服务器(nvt)设备。我按照gsoap's website中给出的说明和typemap.dat进行代码生成。我使用" -P"和" -x" wsdl2h和" -S -i -x -w"的参数对于soapcpp2。一切都按预期工作,但有一点怪癖。

ONVIF核心规范定义了GetServices()动作,其中包括一个可选的"功能"成员在"服务"实现。由于可选成员不是由wsdl2h创建的(由于我的参数,我猜),我对我的typemap文件进行了以下修改:

_tds__Service_Capabilities = $ xsd__anyType * Capabilities;

然后,我可以根据服务类型实现,根据ONVIF规范的要求将自定义/派生的Capabilities对象分配给该成员。但是,最终的Capabilities对象始终使用与GetServices()操作相同的命名空间来表示,这不是所需的操作。例如,这里是预期的响应(简化):

<tds:Service>
    <tds:Capabilities>
        <tds:Capabilities>
        </tds:Capabilities>
    </tds:Capabilities>
</tds:Service>
<tds:Service>
    <tds:Capabilities>
        <trt:Capabilities>
        ...
        </trt:Capabilities>
    </tds:Capabilities>
</tds:Service>
<tds:Service>
    <tds:Capabilities>
        <tev:Capabilities>
            ...
        </tev:Capabilities>
    </tds:Capabilities>
</tds:Service>

而实际的反应是:

<tds:Service>
    <tds:Capabilities>
        <tds:Capabilities>
        </tds:Capabilities>
    </tds:Capabilities>
</tds:Service>
<tds:Service>
    <tds:Capabilities>
        <tds:Capabilities>
        ...
        </tds:Capabilities>
    </tds:Capabilities>
</tds:Service>
<tds:Service>
    <tds:Capabilities>
        <tds:Capabilities>
            ...
        </tds:Capabilities>
    </tds:Capabilities>
</tds:Service>

为克服这个怪癖,我将以下丑陋的补丁应用于创建soapC.cpp文件:

@@ -42068,7 +51777,7 @@ void tev__Capabilities::soap_serialize(struct soap *soap) const

 int tev__Capabilities::soap_out(struct soap *soap, const char *tag, int id, const char *type) const
 {
-   return soap_out_tev__Capabilities(soap, "tev:Capabilities", id, this, type);
+   return soap_out_tev__Capabilities(soap, tag, id, this, type);
 }

 SOAP_FMAC3 int SOAP_FMAC4 soap_out_tev__Capabilities(struct soap *soap, const char *tag, int id, const tev__Capabilities *a, const char *type)
@@ -64741,7 +74450,7 @@ void trt__Capabilities::soap_serialize(struct soap *soap) const

 int trt__Capabilities::soap_out(struct soap *soap, const char *tag, int id, const char *type) const
 {
-   return soap_out_trt__Capabilities(soap, "trt:Capabilities", id, this, type);
+   return soap_out_trt__Capabilities(soap, tag, id, this, type);
 }

我每次重新生成文件时都必须应用此补丁,我非常担心这可能会在将来导致一些兼容性问题。覆盖命名空间标记的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

不应该在typemap.dat文件中进行修改,您应该可以使用gSOAP dom api执行此操作。

为了允许将DOM元素分配给xsd_anyType,您应该将-d添加到wsdl2h命令:

  

-d使用DOM填充xs:any和xsd:anyType元素

然后是专门的能力结构,分配如下:

tev__Capabilities *tevcapabilities = soap_new_tev__Capabilities(soap);

可以设置为_any结构的tds::Capabilities字段,如下所示:

tds__Service_Capabilities *capabilities = soap_new__tds__Service_Capabilities(soap);
capabilities->__any = soap_dom_element(soap, NULL, "tev:Capabilities", 
                          tevcapabilities, tevcapabilities->soap_type());