Я играл с gSOAP XML Binding и заметил, что генерация классов варьируется в зависимости от стиля схемы XML.Позвольте мне показать вам пример:
library.xml :
<?xml version="1.0" encoding="UTF-8"?>
<library>
<book isbn="0132350882"/>
<book isbn="020161622X"/>
<book isbn="0201633612"/>
</library>
Случай 1: XML-схема, написанная в стиле русской куклы
library.xsd (стиль русской куклы - сгенерированный Visual Studio 2010 из XML выше):
<?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>
Я использую следующую последовательность для получения файлов прокси(заголовок и источник):
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
Для XSD gSOAP в стиле русской куклы создаются классы со следующим дизайном:
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 */
...
};
Обратите внимание, что _ns1__library
член book
реализован как вектор _ns1__library_book
объектов .Но это не тот случай, когда мы предоставляем схему, написанную в других стилях, где она реализована как вектор указателей .
Случай 2: XML-схема, написанная в стиле жалюзи
library.xsd (жалюзи):
<?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 */
...
};
Случай 3: XML-схема, написанная в стиле нарезанных салями
library.xsd (нарезанные салями):
<?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 */
...
}
Для предоставленного XML я предпочитаю, чтобы элемент коллекций книг _ns1__library
был вектором объектов, а не вектором указателей.Я хочу создать экземпляр _ns1__book
в стеке и просто передать его (по ссылке) в push_back()
вектора.Это возможно только для русских схем в стиле кукол.
Как заставить gSOAP сгенерировать коллекцию элементов-элементов как вектор объектов для любого стиля схемы?Должны ли быть предоставлены некоторые специальные аргументы для wsdl2h.exe и / или soapcpp2.exe ?Должен ли документ схемы XML содержать какие-либо дополнительные элементы?