17 #include <QXmlStreamReader>
19 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
20 #define QStringView QStringRef
23 static QStringView
namespaceForPrefix(
const QXmlStreamNamespaceDeclarations &decls,
const QString &prefix)
25 for (
const QXmlStreamNamespaceDeclaration &decl : qAsConst(decls)) {
26 if (decl.prefix() == prefix) {
27 return decl.namespaceUri();
40 } s_types[] = {{
"string", QVariant::String},
41 {
"base64Binary", QVariant::ByteArray},
42 {
"int", QVariant::Int},
43 {
"unsignedInt", QVariant::ULongLong},
44 {
"boolean", QVariant::Bool},
45 {
"float", QMetaType::Float},
46 {
"double", QVariant::Double},
47 {
"time", QVariant::Time},
48 {
"date", QVariant::Date}};
50 for (
const auto &type : s_types) {
51 if (xmlType == QLatin1String(type.xml)) {
52 return type.metaTypeId;
55 if (xmlType == QLatin1String(
"dateTime")) {
56 return qMetaTypeId<KDDateTime>();
66 const QXmlStreamNamespaceDeclarations combinedNamespaceDeclarations = envNsDecls + reader.
namespaceDeclarations();
67 const QString name = reader.name().toString();
73 QVariant::Type metaTypeId = QVariant::Invalid;
75 const QXmlStreamAttributes attributes = reader.attributes();
76 for (
const QXmlStreamAttribute &attribute : attributes) {
77 const QStringView name = attribute.name();
78 const QStringView ns = attribute.namespaceUri();
79 const QStringView attrValue = attribute.value();
83 if (name == QLatin1String(
"type")) {
85 const QString type = attrValue.toString();
86 const int pos = type.indexOf(QLatin1Char(
':'));
87 const QString dataType = type.mid(pos + 1);
100 while (reader.readNext() != QXmlStreamReader::Invalid) {
101 if (reader.isEndElement()) {
104 if (reader.isCharacters()) {
105 text = reader.text().toString();
107 }
else if (reader.isStartElement()) {
113 if (!text.isEmpty()) {
114 QVariant variant(text);
118 if (metaTypeId != QVariant::Invalid) {
119 QVariant copy = variant;
120 if (!variant.convert(metaTypeId)) {
136 int symbol = charRef.indexOf(
'x');
137 int end = charRef.indexOf(
';');
139 if (symbol == -1 || end == -1) {
143 uint val = charRef.mid(symbol + 1, end - symbol - 1).toInt(&ok, 16);
149 if (val != 0x9 && val != 0xa && val != 0xd && (val <= 0x20)) {
158 qint64 i = offset - 1;
159 QByteArray dataCleanedUp;
160 QByteArray originalSequence;
162 while (i >= 0 && data.at(i) !=
'&') {
163 if (data.at(i) ==
'<') {
164 return dataCleanedUp;
167 originalSequence.prepend(data.at(i));
172 qWarning() <<
"found an invalid character sequence to remove:" << QLatin1String(originalSequence.prepend(
'&').constData());
173 dataCleanedUp = data;
174 dataCleanedUp = dataCleanedUp.replace(originalSequence,
"?");
176 return dataCleanedUp;
183 QXmlStreamReader reader(data);
184 if (reader.readNextStartElement()) {
185 if (reader.name() == QLatin1String(
"Envelope")
188 const QXmlStreamNamespaceDeclarations envNsDecls = reader.namespaceDeclarations();
189 if (reader.readNextStartElement()) {
190 if (reader.name() == QLatin1String(
"Header")
194 while (reader.readNextStartElement()) {
197 messageAddressingProperties.readMessageAddressingProperty(value);
201 pRequestHeaders->append(header);
205 reader.readNextStartElement();
207 if (reader.name() == QLatin1String(
"Body")
210 if (reader.readNextStartElement()) {
212 if (pMessageNamespace) {
215 if (pMsg->
name() == QLatin1String(
"Fault")
223 reader.raiseError(QObject::tr(
"Invalid SOAP Message, Body expected"));
226 reader.raiseError(QObject::tr(
"Invalid SOAP Message, empty Envelope"));
229 reader.raiseError(QObject::tr(
"Invalid SOAP Message, Envelope expected"));
232 if (reader.hasError()) {
233 if (reader.error() == QXmlStreamReader::NotWellFormedError) {
234 qWarning() <<
"Handling a Not well Formed Error";
236 if (!dataCleanedUp.isEmpty()) {
237 return xmlToMessage(dataCleanedUp, pMsg, pMessageNamespace, pRequestHeaders, soapVersion);
240 QString faultText = QString::fromLatin1(
"XML error: [%1:%2] %3")
241 .arg(QString::number(reader.lineNumber()), QString::number(reader.columnNumber()), reader.errorString());
static QStringView namespaceForPrefix(const QXmlStreamNamespaceDeclarations &decls, const QString &prefix)
static QByteArray handleNotWellFormedError(const QByteArray &data, qint64 offset)
static KDSoapValue parseElement(QXmlStreamReader &reader, const QXmlStreamNamespaceDeclarations &envNsDecls)
static int xmlTypeToMetaType(const QString &xmlType)
static bool isInvalidCharRef(const QByteArray &charRef)
static bool isWSAddressingNamespace(const QString &namespaceUri)
XmlError xmlToMessage(const QByteArray &data, KDSoapMessage *pParsedMessage, QString *pMessageNamespace, KDSoapHeaders *pRequestHeaders, KDSoap::SoapVersion soapVersion) const
@ PrematureEndOfDocumentError
void setMessageAddressingProperties(const KDSoapMessageAddressingProperties &map)
void createFaultMessage(const QString &faultCode, const QString &faultText, KDSoap::SoapVersion soapVersion)
void setFault(bool fault)
static QString soapEncoding()
static QString soapEnvelope()
static QString xmlSchemaInstance1999()
static QString xmlSchemaInstance2001()
static QString soapEnvelope200305()
static QString soapEncoding200305()
QList< KDSoapValue > & attributes()
KDSoapValueList & childValues() const
QXmlStreamNamespaceDeclarations namespaceDeclarations() const
void setNamespaceUri(const QString &ns)
QString namespaceUri() const
void setType(const QString &nameSpace, const QString &type)
void setNamespaceDeclarations(const QXmlStreamNamespaceDeclarations &namespaceDeclarations)
void setValue(const QVariant &value)
void setEnvironmentNamespaceDeclarations(const QXmlStreamNamespaceDeclarations &environmentNamespaceDeclarations)