QDomNode QDomDocumentProto::lastChild() const { QDomDocument *item = qscriptvalue_cast<QDomDocument*>(thisObject()); if (item) return item->lastChild(); return QDomNode(); }
// The QHttp object retrieved data. void Service::slotRequestFinished() { QNetworkReply * reply = qobject_cast<QNetworkReply *>(sender()); qDebug() << "UPnP::Service: received HTTP response for request " << endl; if(!reply) { qWarning() << "UPnP::Service - HTTP Request failed: " << reply->errorString() << endl; m_iPendingRequests--; emit queryFinished(true); return; } if(reply->error() != QNetworkReply::NoError) { qWarning() << "UPnP::Service - HTTP Request failed: " << reply->errorString() << endl; m_iPendingRequests--; emit queryFinished(true); reply->deleteLater(); return; } // Get the XML content QByteArray response = reply->readAll(); QDomDocument xml; qDebug() << "Response:\n" << response << "\n---\n"; // Parse the XML QString errorMessage; bool error = !xml.setContent(response, false, &errorMessage); if(!error) { QString baseNamespace = xml.documentElement().tagName(); if(baseNamespace.length() > 0) { int cutAt = baseNamespace.indexOf(':'); if(cutAt > -1) { baseNamespace.truncate(cutAt); qDebug() << "Device is using " << baseNamespace << " as XML namespace" << endl; m_szBaseXmlPrefix = baseNamespace; } } // Determine how to process the data if(xml.namedItem(m_szBaseXmlPrefix + ":Envelope").isNull()) { qDebug() << "UPnP::Service: plain XML detected, calling gotInformationResponse()." << endl; // No SOAP envelope found, this is a normal response to callService() gotInformationResponse(xml.lastChild()); } else { qDebug() << xml.toString() << endl; // Got a SOAP message response to callAction() QDomNode resultNode = XmlFunctions::getNode(xml, "/" + m_szBaseXmlPrefix + ":Envelope/" + m_szBaseXmlPrefix + ":Body").firstChild(); error = (resultNode.nodeName() == m_szBaseXmlPrefix + ":Fault"); if(!error) { if(resultNode.nodeName().startsWith("m:") || resultNode.nodeName().startsWith("u:")) { qDebug() << "UPnP::Service: SOAP envelope detected, calling gotActionResponse()." << endl; // Action success, return SOAP body QMap<QString, QString> resultValues; // Parse all parameters // It's possible to pass the entire QDomNode object to the gotActionResponse() // function, but this is somewhat nicer, and reduces code boat in the subclasses QDomNodeList children = resultNode.childNodes(); for(int i = 0; i < children.count(); i++) { QString key = children.item(i).nodeName(); resultValues[key] = children.item(i).toElement().text(); } // Call the gotActionResponse() gotActionResponse(resultNode.nodeName().mid(2), resultValues); } } else { qDebug() << "UPnP::Service: SOAP error detected, calling gotActionResponse()." << endl; // Action failed gotActionErrorResponse(resultNode); } } } else { qWarning() << "UPnP::Service - XML parsing failed: " << errorMessage << endl; } // Only emit when bytes>0 m_iPendingRequests--; emit queryFinished(error); }