Я пытаюсь реализовать устройство сервера ONVIF (nvt) с помощью gsoap. Я следую инструкциям и typemap.dat, приведенным в веб-сайт Gsoap для генерации кода. Я использую параметры «-P» и «-x» для wsdl2h и «-S -i -x -w» для soapcpp2. Все работает как положено, но есть небольшая странность.
Базовая спецификация ONVIF определяет действие GetServices (), которое включает в себя необязательный член «Возможности» в своем ответе под реализацией «Служба». Поскольку необязательные элементы не создаются wsdl2h (из-за моих параметров, я думаю), я делаю следующую модификацию в моем файле карты типов:
_tds__Service_Capabilities = $ xsd__anyType * Capabilities;
Затем я могу назначить пользовательские / производные объекты Capabilities этому члену, как того требует спецификация ONVIF, в зависимости от реализации типа сервиса. Однако конечный объект 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);
}
Мне приходится применять этот патч каждый раз, когда я заново генерирую файлы, и у меня есть серьезные опасения, что это может вызвать проблемы с совместимостью в будущем. Как правильно переопределить теги пространства имен?
Не нужно вносить изменения в файл typemap.dat, вы должны сделать это, используя gSOAP dom api.
Чтобы разрешить назначать элемент DOM xsd_anyType
ты должен добавить -d
к команде wsdl2h:
-использовать DOM для заполнения элементов xs: any и xsd: anyType
Тогда специализированная структура capabilitites, которая выделяется чем-то вроде:
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());
Других решений пока нет …