Если это помогает, недавний выпуск инструментария gsoap 2.8.34 теперь поддерживает минимализацию сериализации примитивных типов QT и контейнеров QT в XML с минимальными усилиями.
Типы QT привязаны к типам XSD по имени, в основном просто typedef. Эти типы затем сериализуются с использованием настраиваемого сериализатора, который скомпилирован и связан с вашим кодом.
Возможно, это проще понять с помощью простого примера.
Чтобы использовать QString
как сериализуемый тип, просто добавьте #import "custom/qstring.h"
в файл заголовка, у которого есть интерфейс привязки данных для soapcpp2. Затем запустите soapcpp2 в файле и скомпилируйте сгенерированный soapC.cpp
с stdsoap2.cpp
. Не забудьте указать #include "soapH.h"
(который также включает soapStub.h
).
Вот пример файла заголовка для soapcpp2 с типами, которые вы хотите сериализовать в XML, объявляя их привязки данных и импортировать пользовательские типы QT, которые вы хотите:
////////////////////////////////////////////////////////////////////////////
//
// Import the QT types that we want to bind to XSD types xsd__Type
//
////////////////////////////////////////////////////////////////////////////
#import "custom/qstring.h" // typedef QString xsd__string
#import "custom/qbytearray_base64.h" // typedef QByteArray xsd__base64Binary
////////////////////////////////////////////////////////////////////////////
//
// Declare QT container template(s) we will use
//
////////////////////////////////////////////////////////////////////////////
template <class T> class QList;
////////////////////////////////////////////////////////////////////////////
//
// Define an XML namespace "ns" for our schema
//
////////////////////////////////////////////////////////////////////////////
//gsoap ns schema namespace: urn:MyTypes
////////////////////////////////////////////////////////////////////////////
//
// Define C++ types that use the xsd__Type QT types imported above
//
////////////////////////////////////////////////////////////////////////////
class ns:MyStruct
{
public:
xsd__string x; // a QString object
xsd__base64Binary y; // a QByteArray object
};
class ns:MyData
{
public:
QList<ns:MyStruct> z; // a QT list of MyStruct
};
Обратите внимание, что я оставил его простым, используя ns:
в качестве префикса, а не ns__
(ns
с двойными символами подчеркивания). Разница в том, что ns:
будет не быть частью ваших имен типа C++, тогда как ns__
будет быть частью ваших имен типа C++. Это конвенция gsoap.
После запуска soapcpp2 на этот файл заголовка, он генерирует схему ns.xsd
с типами XML:
<schema targetNamespace="urn:MyTypes"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:ns="urn:MyTypes"
xmlns="http://www.w3.org/2001/XMLSchema"
elementFormDefault="unqualified"
attributeFormDefault="unqualified">
<import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
<complexType name="MyStruct"><!-- ns:MyStruct -->
<sequence>
<element name="x" type="xsd:string" minOccurs="1" maxOccurs="1"/><!-- ns:MyStruct::x -->
<element name="y" type="xsd:base64Binary" minOccurs="1" maxOccurs="1"/><!-- ns:MyStruct::y -->
</sequence>
</complexType>
<complexType name="MyData"><!-- ns:MyData -->
<sequence>
<element name="z" type="ns:MyStruct" minOccurs="0" maxOccurs="unbounded"/><!-- ns:MyData::z -->
</sequence>
</complexType>
</schema>
Вы можете избавиться от SOAP материала с опцией -0
(черточки ноль) для soapcpp2.
Если вы хотите определить корневой элемент для MyData
в этой схеме, то добавьте следующую строку в файл заголовка и запускать soapcpp2 на данный файл:
typedef ns:MyData _ns__myRoot; // ns:myRoot is an XML element of type ns:MyData
XML-сериализатор можно использовать следующим образом:
#include "soapH.h" // this is generated by soapcpp2
#include "ns.nsmap" // this is generated by soapcpp2
...
soap *ctx = soap_new1(SOAP_XML_INDENT); // create a context
MyData data;
...
data.push_back(MyStruct()); // populate some data
ctx->os = &std::cout;
soap_write__ns__myRoot(ctx, &data); // serialize data in XML
...
ctx->is = &std::cin;
soap_read__ns__myRoot(ctx, &data); // parse data from XML
...
soap_destroy(ctx);
soap_end(ctx);
soap_free(ctx).
Надеюсь, это поможет.
Инструмент soapcpp2 не распознает 'QString' и другие типы QT. Чтобы сериализовать их непосредственно в XML, вам нужно будет определить пользовательские сериализаторы. В противном случае я бы использовал стандартные типы C++ для сериализации и преобразования в/из типов QT. Возможно, вы можете предложить разработчикам gsoap внедрить сериализаторы типа QT? –
Мне это нужно сейчас. Пока разработчик gsoap не реализует это ... – ebigood