QByteArray KDSoapValue::toXml(KDSoapValue::Use use, const QString &messageNamespace) const { QByteArray data; QXmlStreamWriter writer(&data); writer.writeStartDocument(); KDSoapNamespacePrefixes namespacePrefixes; namespacePrefixes.writeStandardNamespaces(writer); writeElement(namespacePrefixes, writer, use, messageNamespace, false); writer.writeEndDocument(); return data; }
void KDSoapValue::writeElementContents(KDSoapNamespacePrefixes &namespacePrefixes, QXmlStreamWriter &writer, KDSoapValue::Use use, const QString &messageNamespace) const { const QVariant value = this->value(); if (isNil() && d->m_nillable) { writer.writeAttribute(KDSoapNamespaceManager::xmlSchemaInstance2001(), QLatin1String("nil"), QLatin1String("true")); } if (use == EncodedUse) { // use=encoded means writing out xsi:type attributes. http://www.eherenow.com/soapfight.htm taught me that. QString type; if (!this->type().isEmpty()) { type = namespacePrefixes.resolve(this->typeNs(), this->type()); } if (type.isEmpty() && !value.isNull()) { type = variantToXMLType(value); // fallback } if (!type.isEmpty()) { writer.writeAttribute(KDSoapNamespaceManager::xmlSchemaInstance2001(), QLatin1String("type"), type); } // cppcheck-suppress redundantCopyLocalConst const KDSoapValueList list = this->childValues(); const bool isArray = !list.arrayType().isEmpty(); if (isArray) { writer.writeAttribute(KDSoapNamespaceManager::soapEncoding(), QLatin1String("arrayType"), namespacePrefixes.resolve(list.arrayTypeNs(), list.arrayType()) + QLatin1Char('[') + QString::number(list.count()) + QLatin1Char(']')); } } writeChildren(namespacePrefixes, writer, use, messageNamespace, false); if (!value.isNull()) { writer.writeCharacters(variantToTextValue(value, this->typeNs(), this->type())); } }
QByteArray KDSoapMessageWriter::messageToXml(const KDSoapMessage &message, const QString &method, const KDSoapHeaders &headers, const QMap<QString, KDSoapMessage> &persistentHeaders) const { QByteArray data; QXmlStreamWriter writer(&data); writer.writeStartDocument(); KDSoapNamespacePrefixes namespacePrefixes; namespacePrefixes.writeStandardNamespaces(writer, m_version, message.hasMessageAddressingProperties()); QString soapEnvelope; QString soapEncoding; if (m_version == KDSoapClientInterface::SOAP1_1) { soapEnvelope = KDSoapNamespaceManager::soapEnvelope(); soapEncoding = KDSoapNamespaceManager::soapEncoding(); } else if (m_version == KDSoapClientInterface::SOAP1_2) { soapEnvelope = KDSoapNamespaceManager::soapEnvelope200305(); soapEncoding = KDSoapNamespaceManager::soapEncoding200305(); } writer.writeStartElement(soapEnvelope, QLatin1String("Envelope")); // This has been removed, see http://msdn.microsoft.com/en-us/library/ms995710.aspx for details //writer.writeAttribute(soapEnvelope, QLatin1String("encodingStyle"), soapEncoding); QString messageNamespace = m_messageNamespace; if (!message.namespaceUri().isEmpty() && messageNamespace != message.namespaceUri()) { messageNamespace = message.namespaceUri(); } if (!headers.isEmpty() || !persistentHeaders.isEmpty() || message.hasMessageAddressingProperties()) { // This writeNamespace line adds the xmlns:n1 to <Envelope>, which looks ugly and unusual (and breaks all unittests) // However it's the best solution in case of headers, otherwise we get n1 in the header and n2 in the body, // and xsi:type attributes that refer to n1, which isn't defined in the body... namespacePrefixes.writeNamespace(writer, messageNamespace, QLatin1String("n1") /*make configurable?*/); writer.writeStartElement(soapEnvelope, QLatin1String("Header")); Q_FOREACH (const KDSoapMessage &header, persistentHeaders) { header.writeChildren(namespacePrefixes, writer, header.use(), messageNamespace, true); }