You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在gSOAP的SOAP-ENV:Header中添加多个直接子元素?

问题:gSOAP生成ONVIF协议要求的多直接子元素SOAP Header失败

需要生成符合ONVIF协议的SOAP报文,其中SOAP-ENV:Header需包含多个直接子元素(如dom0:SubscriptionId、dom1:SubscriptionId)。使用gSOAP生成的SOAP_ENV__Header结构体中的__any字段尝试添加自定义子元素时,通过soap_elt_new构建的next链表仅第一个元素被序列化,无法满足需求。

解决方案

1. 正确构建soap_dom_element链表并配置元素属性

gSOAP的__any字段支持通过next指针链接多个同级元素,需确保每个元素正确初始化命名空间、属性和文本内容:

// 创建第一个SubscriptionId元素,指定命名空间前缀、名称和URI
struct soap_dom_element *subId1 = soap_elt_new(m_event_proxy.Get(), "dom0", "SubscriptionId", "http://trololo/111/event");
// 添加wsa5:IsReferenceParameter属性
soap_elt_add_attr(m_event_proxy.Get(), subId1, "wsa5", "IsReferenceParameter", "http://www.w3.org/2005/08/addressing", "true");
// 设置元素文本内容
soap_elt_set_text(m_event_proxy.Get(), subId1, "1715065920077");

// 创建第二个SubscriptionId元素
struct soap_dom_element *subId2 = soap_elt_new(m_event_proxy.Get(), "dom1", "SubscriptionId", "http://trololo/222/event");
soap_elt_add_attr(m_event_proxy.Get(), subId2, "wsa5", "IsReferenceParameter", "http://www.w3.org/2005/08/addressing", "true");
soap_elt_set_text(m_event_proxy.Get(), subId2, "1715065920078");

// 链接元素链表
subId1->next = subId2;
// 将链表赋值给Header的__any字段
m_event_proxy.Get()->header->__any = subId1;

2. 自定义WSDL生成专属Header结构体(可选)

修改ONVIF的WSDL文件,添加SubscriptionId元素的定义,重新生成gSOAP代码。这样SOAP_ENV__Header结构体中会直接包含对应的字段,无需手动操作DOM元素。注意:这种方法需要维护自定义WSDL,版本升级时需同步调整。

3. 手动序列化Header元素

在调用服务方法前,绕过自动序列化逻辑,手动写入Header元素:

// 手动插入第一个SubscriptionId元素
soap_begin_elt(m_event_proxy.Get(), m_event_proxy.Get()->header, "dom0", "SubscriptionId", "http://trololo/111/event");
soap_add_attr(m_event_proxy.Get(), "wsa5", "IsReferenceParameter", "http://www.w3.org/2005/08/addressing", "true");
soap_put_text(m_event_proxy.Get(), "1715065920077");
soap_end_elt(m_event_proxy.Get());

// 手动插入第二个SubscriptionId元素
soap_begin_elt(m_event_proxy.Get(), m_event_proxy.Get()->header, "dom1", "SubscriptionId", "http://trololo/222/event");
soap_add_attr(m_event_proxy.Get(), "wsa5", "IsReferenceParameter", "http://www.w3.org/2005/08/addressing", "true");
soap_put_text(m_event_proxy.Get(), "1715065920078");
soap_end_elt(m_event_proxy.Get());

问题原因

之前的代码未指定元素的命名空间,也未设置必要的属性和文本内容,导致gSOAP序列化时无法正确识别后续元素,仅处理第一个节点。

内容的提问来源于stack exchange,提问作者Danil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 11:25:09