How to get gSOAP to generate a vector of objects (not pointers!) For any XSD style?

I played with gSOAP XML Data Binding and noticed that class generation varies depending on the style of the XML schema. Let me show you an example:

Library.xml

<?xml version="1.0" encoding="UTF-8"?> <library> <book isbn="0132350882"/> <book isbn="020161622X"/> <book isbn="0201633612"/> </library> 

Case 1: An XML Schema Written in Russian Doll Style

library.xsd (Russian doll style created by Visual Studio 2010 from XML above):

 <?xml version="1.0" encoding="utf-8"?> <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="library"> <xs:complexType> <xs:sequence> <xs:element maxOccurs="unbounded" name="book"> <xs:complexType> <xs:attribute name="isbn" type="xs:string" use="required" /> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> 

I use the following sequence to get proxy files (header and source):

c:\test\gSOAP_Test1>wsdl2h.exe -t "c:\tools\gsoap_2.8.6\gsoap-2.8\gsoap\typemap.dat" Library.xsd

c:\test\gSOAP_Test1>soapcpp2.exe -I "c:\tools\gsoap_2.8.6\gsoap-2.8\gsoap\import" Library.h

For a Russian doll XSD gSOAP generates classes with the following design:

soapStub.h

 class SOAP_CMAC _ns1__library_book { public: std::string isbn; /* required attribute */ ... }; class SOAP_CMAC _ns1__library { public: std::vector<_ns1__library_book >book; /* required element of type ns1:library-book */ ... }; 

Note that the _ns1__library member book is implemented as a vector of _ns1__library_book objects . But this is not the case when we provide a scheme written in other styles, where it is implemented as a vector of pointers .

Case 2: An XML Schema Written in the Style of a Venetian Nugget

library.xsd (blinds):

 <?xml version="1.0" encoding="utf-8"?> <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:complexType name="book_t"> <xs:attribute name="isbn" type="xs:string" use="required"/> </xs:complexType> <xs:complexType name="library_t"> <xs:sequence> <xs:element name="book" type="book_t" minOccurs="1" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> <xs:element name="library" type="library_t"/> </xs:schema> 

soapStub.h

 class SOAP_CMAC ns1__book_USCOREt { public: std::string isbn; /* required attribute */ ... }; #endif class SOAP_CMAC ns1__library_USCOREt { public: std::vector<ns1__book_USCOREt * >book; /* required element of type ns1:book_t */ ... }; 

Case 3: An XML Schema Written in Salami Slicing Style

library.xsd (sliced ​​salami):

 <?xml version="1.0" encoding="utf-8"?> <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="book"> <xs:complexType> <xs:attribute name="isbn" type="xs:string" use="required"/> </xs:complexType> </xs:element> <xs:element name="library"> <xs:complexType> <xs:sequence> <xs:element ref="book" minOccurs="1" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> 

soapStub.h

 class SOAP_CMAC _ns1__book { public: std::string isbn; /* required attribute */ ... }; #endif class SOAP_CMAC _ns1__library { public: std::vector<_ns1__book * >ns1__book; /* required element of type ns1:book */ ... } 

For the XML provided, I prefer the _ns1__library member of book collections to be an object vector rather than a pointer vector. I want to create an instance of _ns1__book on the stack and just pass it (by reference) to the push_back() vector. This is possible only for Russian puppet schemes.

How to make gSOAP generate a collection of elements as a vector of objects for any circuit style? Should there be any special arguments for wsdl2h.exe and / or soapcpp2.exe? Should the XML schema document contain any additional elements?

+4
source share

Source: https://habr.com/ru/post/1395084/


All Articles