在 gsoap 中生成 SOAP-ENV:Header 的子元素时出现问题

问题描述 投票:0回答:1

我想创建这样的东西:

    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:c14n="http://www.w3.org/2001/10/xml-exc-c14n#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:saml1="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" xmlns:wsc="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:chan="http://schemas.microsoft.com/ws/2005/02/duplex" xmlns:wsa5="http://www.w3.org/2005/08/addressing" xmlns:pt="http://www.onvif.org/ver10/pacs" xmlns:ns1="http://www.onvif.org/ver20/analytics/humanface" xmlns:ns2="http://www.onvif.org/ver20/analytics/humanbody" xmlns:xmime="http://tempuri.org/xmime.xsd" xmlns:xop="http://www.w3.org/2004/08/xop/include" xmlns:tt="http://www.onvif.org/ver10/schema" xmlns:wsrfbf="http://docs.oasis-open.org/wsrf/bf-2" xmlns:wstop="http://docs.oasis-open.org/wsn/t-1" xmlns:wsrfr="http://docs.oasis-open.org/wsrf/r-2" xmlns:tac="http://www.onvif.org/ver10/accesscontrol/wsdl" xmlns:tds="http://www.onvif.org/ver10/device/wsdl" xmlns:tev="http://www.onvif.org/ver10/events/wsdl" xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2" xmlns:timg="http://www.onvif.org/ver20/imaging/wsdl" xmlns:tmd="http://www.onvif.org/ver10/deviceIO/wsdl" xmlns:tptz="http://www.onvif.org/ver20/ptz/wsdl" xmlns:trp="http://www.onvif.org/ver10/replay/wsdl" xmlns:trt="http://www.onvif.org/ver10/media/wsdl" xmlns:tse="http://www.onvif.org/ver10/search/wsdl">
     <SOAP-ENV:Header>
      <dom0:SubscriptionId wsa5:IsReferenceParameter="true" xmlns:dom0="http://trololo/111/event">1715065920077</dom0:SubscriptionId>
      <dom1:SubscriptionId wsa5:IsReferenceParameter="true" xmlns:dom0="http://trololo/222/event">1715065920078</dom0:SubscriptionId>
      <wsa5:MessageID>urn:uuid:654721e3-4c2e-45ec-a1f3-f581309c6428</wsa5:MessageID>
      <wsa5:To SOAP-ENV:mustUnderstand="true">http://127.0.0.1:8088/mockEventsBinding/1715065920077</wsa5:To>
      <wsa5:Action SOAP-ENV:mustUnderstand="true">http://docs.oasis-open.org/wsn/bw-2/SubscriptionManager/RenewRequest</wsa5:Action>
    </SOAP-ENV:Header>
    <SOAP-ENV:Body>
      <wsnt:Renew>
         <wsnt:TerminationTime>PT30S</wsnt:TerminationTime>
      </wsnt:Renew>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

所以我需要在标头中添加几个子项(dom0:SubscriptionId、dom1:SubscriptionId)

gsoap生成了这样一个结构:

struct SOAP_CMAC SOAP_ENV__Header {
      public:
        /** MustUnderstand */
        struct _wsse__Security *wsse__Security;
        /** XML DOM element node graph */
        struct soap_dom_element *__any;
        /** Optional element 'wsa5:MessageID' of XML schema type 'wsa5:MessageID' */
        char *wsa5__MessageID;
        /** Optional element 'wsa5:RelatesTo' of XML schema type 'wsa5:RelatesTo' */
        struct wsa5__RelatesToType *wsa5__RelatesTo;
        /** Optional element 'wsa5:From' of XML schema type 'wsa5:From' */
        struct wsa5__EndpointReferenceType *wsa5__From;
        /** MustUnderstand */
        struct wsa5__EndpointReferenceType *wsa5__ReplyTo;
        /** MustUnderstand */
        struct wsa5__EndpointReferenceType *wsa5__FaultTo;
        /** MustUnderstand */
        char *wsa5__To;
        /** MustUnderstand */
        char *wsa5__Action;
        /** Optional element 'chan:ChannelInstance' of XML schema type 'chan:ChannelInstanceType' */
        struct chan__ChannelInstanceType *chan__ChannelInstance;
      public:
        /** Return unique type id SOAP_TYPE_SOAP_ENV__Header */
        long soap_type() const { return SOAP_TYPE_SOAP_ENV__Header; }
        /** Constructor with member initializations */
        SOAP_ENV__Header() : wsse__Security(), __any(), wsa5__MessageID(), wsa5__RelatesTo(), wsa5__From(), wsa5__ReplyTo(), wsa5__FaultTo(), wsa5__To(), wsa5__Action(), chan__ChannelInstance() { }
        /** Friend allocator */
        friend SOAP_FMAC1 SOAP_ENV__Header * SOAP_FMAC2 soap_instantiate_SOAP_ENV__Header(struct soap*, int, const char*, const char*, size_t*);
};

我需要使用

struct soap_dom_element *__any;
添加我的孩子。 然而这是不可能的。我只能添加带有子节点的单个节点,例如:

<SOAP-ENV:Header><parent><child1/><child2/></parent></SOAP-ENV:Header>

但无法添加没有父项的子项。 (虽然onvif协议要求)

所以我尝试将 elts 设置为 __any,结果我只序列化了第一个子元素。看起来像 gsoap 错误。

创建结构的方式:

        auto first = soap_elt_new(m_event_proxy.Get(), nullptr, "test1");
        first->next = soap_elt_new(m_event_proxy.Get(), nullptr, "test2");
        first->next->next = soap_elt_new(m_event_proxy.Get(), nullptr, "test3");
        m_event_proxy.Get()->header->__any = first;

其中 m_event_proxy 是

SoapInitializer<PullPointSubscriptionBindingProxy> ;

c++ xml gsoap onvif
1个回答
0
投票

好吧,诀窍是像这样创建一个父空节点并设置它的类型:

m_parameter = soap_elt_new(m_soap, nullptr, nullptr);
m_parameter->type = SOAP_TYPE__XML;

然后我们应该将节点添加为子节点:

auto parameter1 = soap_elt_new(m_soap, nullptr, "test1");
soap_add_elt(m_parameter, parameter1);
auto parameter2 = soap_elt_new(m_soap, nullptr, "test2");
soap_add_elt(m_parameter, parameter2);

宾果游戏

© www.soinside.com 2019 - 2024. All rights reserved.