Add an option to use tinyxml instead of pugixml.
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
#include "csoap/common.h"
|
||||
|
||||
#include "boost/lexical_cast.hpp"
|
||||
|
||||
namespace csoap {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
// Common definitions.
|
||||
|
||||
#include <string>
|
||||
#include "boost/lexical_cast.hpp"
|
||||
|
||||
namespace csoap {
|
||||
|
||||
@@ -56,18 +55,10 @@ public:
|
||||
Parameter(const std::string& key, double value);
|
||||
Parameter(const std::string& key, bool value);
|
||||
|
||||
const char* c_key() const {
|
||||
return key_.c_str();
|
||||
}
|
||||
|
||||
const std::string& key() const {
|
||||
return key_;
|
||||
}
|
||||
|
||||
const char* c_value() const {
|
||||
return value_.c_str();
|
||||
}
|
||||
|
||||
const std::string& value() const {
|
||||
return value_;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "boost/bind.hpp"
|
||||
#include "boost/algorithm/string.hpp"
|
||||
#include "boost/lexical_cast.hpp"
|
||||
|
||||
#include "csoap/common.h"
|
||||
|
||||
|
||||
@@ -5,11 +5,22 @@ namespace csoap {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef CSOAP_USE_TINYXML
|
||||
|
||||
// Append "xmlns" attribute.
|
||||
static void AppendAttrNS(pugi::xml_node& xnode, const Namespace& ns) {
|
||||
xml::AppendAttr(xnode, "xmlns", ns.name, ns.url);
|
||||
static void AddNSAttr(TiXmlElement* xnode, const Namespace& ns) {
|
||||
xml::AddAttr(xnode, "xmlns", ns.name, ns.url);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// Append "xmlns" attribute.
|
||||
static void AddNSAttr(pugi::xml_node& xnode, const Namespace& ns) {
|
||||
xml::AddAttr(xnode, "xmlns", ns.name, ns.url);
|
||||
}
|
||||
|
||||
#endif // CSOAP_USE_TINYXML
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SoapRequest::SoapRequest(const std::string& operation)
|
||||
@@ -28,11 +39,35 @@ void SoapRequest::AddParameter(const Parameter& parameter) {
|
||||
}
|
||||
|
||||
void SoapRequest::ToXmlString(std::string* xml_string) {
|
||||
#ifdef CSOAP_USE_TINYXML
|
||||
|
||||
TiXmlDocument xdoc;
|
||||
TiXmlElement* xroot = xml::AppendChild(&xdoc, soapenv_ns_.name, "Envelope");
|
||||
|
||||
AddNSAttr(xroot, soapenv_ns_);
|
||||
AddNSAttr(xroot, service_ns_);
|
||||
|
||||
xml::AppendChild(xroot, soapenv_ns_.name, "Header");
|
||||
|
||||
TiXmlElement* xbody = xml::AppendChild(xroot, soapenv_ns_.name, "Body");
|
||||
TiXmlElement* xop = xml::AppendChild(xbody, service_ns_.name, operation_);
|
||||
|
||||
for (Parameter& p : parameters_) {
|
||||
TiXmlElement* xparam = xml::AppendChild(xop, service_ns_.name, p.key());
|
||||
xml::SetText(xparam, p.value());
|
||||
}
|
||||
|
||||
TiXmlPrinter printer;
|
||||
xdoc.Accept(&printer);
|
||||
*xml_string = printer.CStr();
|
||||
|
||||
#else
|
||||
|
||||
pugi::xml_document xdoc;
|
||||
pugi::xml_node xroot = xml::AppendChild(xdoc, soapenv_ns_.name, "Envelope");
|
||||
|
||||
AppendAttrNS(xroot, soapenv_ns_);
|
||||
AppendAttrNS(xroot, service_ns_);
|
||||
AddNSAttr(xroot, soapenv_ns_);
|
||||
AddNSAttr(xroot, service_ns_);
|
||||
|
||||
xml::AppendChild(xroot, soapenv_ns_.name, "Header");
|
||||
|
||||
@@ -40,12 +75,14 @@ void SoapRequest::ToXmlString(std::string* xml_string) {
|
||||
pugi::xml_node xop = xml::AppendChild(xbody, service_ns_.name, operation_);
|
||||
|
||||
for (Parameter& p : parameters_) {
|
||||
pugi::xml_node xparam = xml::AppendChild(xop, service_ns_.name, p.c_key());
|
||||
xparam.text().set(p.c_value());
|
||||
pugi::xml_node xparam = xml::AppendChild(xop, service_ns_.name, p.key());
|
||||
xparam.text().set(p.value().c_str());
|
||||
}
|
||||
|
||||
xml::XmlStrRefWriter writer(xml_string);
|
||||
xdoc.print(writer, "\t", pugi::format_default, pugi::encoding_utf8);
|
||||
|
||||
#endif // #ifdef CSOAP_USE_TINYXML
|
||||
}
|
||||
|
||||
} // namespace csoap
|
||||
|
||||
@@ -11,35 +11,73 @@ bool SoapResponse::Parse(const std::string& content,
|
||||
const std::string& message_name,
|
||||
const std::string& element_name,
|
||||
std::string* element_value) {
|
||||
#ifdef CSOAP_USE_TINYXML
|
||||
|
||||
TiXmlDocument xdoc;
|
||||
xdoc.Parse(content.c_str());
|
||||
|
||||
if (xdoc.Error()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TiXmlElement* xroot = xdoc.RootElement();
|
||||
|
||||
soapenv_ns_ = xml::GetNsPrefix(xroot);
|
||||
|
||||
TiXmlElement* xbody = xml::GetChild(xroot, soapenv_ns_, "Body");
|
||||
if (xbody == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TiXmlElement* xmessage = xml::GetChildNoNS(xbody, message_name);
|
||||
if (xmessage == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TiXmlElement* xelement = xml::GetChildNoNS(xmessage, element_name);
|
||||
if (xelement == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* text = xelement->GetText();
|
||||
if (text != NULL) {
|
||||
*element_value = text;
|
||||
} else {
|
||||
*element_value = "";
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
pugi::xml_document xdoc;
|
||||
pugi::xml_parse_result result = xdoc.load_string(content.c_str());
|
||||
|
||||
if (!result) {
|
||||
//std::cout << "Error: " << result.description() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
pugi::xml_node xroot = xdoc.document_element();
|
||||
|
||||
soapenv_ns_ = csoap::xml::GetNsPrefix(xroot);
|
||||
soapenv_ns_ = xml::GetNsPrefix(xroot);
|
||||
|
||||
pugi::xml_node xbody = csoap::xml::GetChild(xroot, soapenv_ns_, "Body");
|
||||
pugi::xml_node xbody = xml::GetChild(xroot, soapenv_ns_, "Body");
|
||||
if (!xbody) {
|
||||
return false;
|
||||
}
|
||||
|
||||
pugi::xml_node xmessage = csoap::xml::GetChildNoNS(xbody, message_name);
|
||||
pugi::xml_node xmessage = xml::GetChildNoNS(xbody, message_name);
|
||||
if (!xmessage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
pugi::xml_node xelement = csoap::xml::GetChildNoNS(xmessage, element_name);
|
||||
pugi::xml_node xelement = xml::GetChildNoNS(xmessage, element_name);
|
||||
if (!xelement) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*element_value = xelement.text().get();
|
||||
|
||||
#endif // CSOAP_USE_TINYXML
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+101
-6
@@ -3,8 +3,14 @@
|
||||
namespace csoap {
|
||||
namespace xml {
|
||||
|
||||
#ifdef CSOAP_USE_TINYXML
|
||||
|
||||
std::string GetNsPrefix(const TiXmlElement* xnode) {
|
||||
std::string node_name = xnode->Value();
|
||||
#else
|
||||
std::string GetNsPrefix(const pugi::xml_node& xnode) {
|
||||
std::string node_name = xnode.name();
|
||||
#endif
|
||||
|
||||
size_t pos = node_name.find(':');
|
||||
|
||||
@@ -15,6 +21,81 @@ std::string GetNsPrefix(const pugi::xml_node& xnode) {
|
||||
return "";
|
||||
}
|
||||
|
||||
#ifdef CSOAP_USE_TINYXML
|
||||
|
||||
TiXmlElement* AppendChild(TiXmlNode* xnode,
|
||||
const std::string& ns,
|
||||
const std::string& name) {
|
||||
std::string ns_name = ns + ":" + name;
|
||||
TiXmlElement* xchild = new TiXmlElement(ns_name.c_str());
|
||||
xnode->LinkEndChild(xchild);
|
||||
return xchild;
|
||||
}
|
||||
|
||||
TiXmlElement* GetChild(TiXmlElement* xnode,
|
||||
const std::string& ns,
|
||||
const std::string& name) {
|
||||
return xnode->FirstChildElement((ns + ":" + name).c_str());
|
||||
}
|
||||
|
||||
TiXmlElement* GetChildNoNS(TiXmlElement* xnode, const std::string& name) {
|
||||
TiXmlElement* xchild = xnode->FirstChildElement();
|
||||
while (xchild != NULL) {
|
||||
std::string child_name = xchild->Value();
|
||||
|
||||
// Remove NS prefix.
|
||||
size_t pos = child_name.find(':');
|
||||
if (pos != std::string::npos) {
|
||||
child_name = child_name.substr(pos + 1);
|
||||
}
|
||||
|
||||
if (child_name == name) {
|
||||
return xchild;
|
||||
}
|
||||
|
||||
xchild = xchild->NextSiblingElement();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void AddAttr(TiXmlElement* xnode,
|
||||
const std::string& ns,
|
||||
const std::string& name,
|
||||
const std::string& value) {
|
||||
std::string ns_name = ns + ":" + name;
|
||||
xnode->SetAttribute(ns_name.c_str(), value.c_str());
|
||||
}
|
||||
|
||||
void SetText(TiXmlElement* xnode, const std::string& text) {
|
||||
if (xnode->FirstChild() == NULL) {
|
||||
xnode->LinkEndChild(new TiXmlText(text.c_str()));
|
||||
} else {
|
||||
xnode->ReplaceChild(xnode->FirstChild(), TiXmlText(text.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
bool PrettyPrintXml(std::ostream& os,
|
||||
const std::string& xml_string,
|
||||
const char* indent) {
|
||||
TiXmlDocument xdoc;
|
||||
xdoc.Parse(xml_string.c_str());
|
||||
|
||||
if (xdoc.Error()) {
|
||||
os << "Invalid XML" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
TiXmlPrinter xprinter;
|
||||
xprinter.SetIndent(indent);
|
||||
xdoc.Accept(&xprinter);
|
||||
os << xprinter.CStr();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
pugi::xml_node AppendChild(pugi::xml_node& xnode,
|
||||
const std::string& ns,
|
||||
const std::string& name) {
|
||||
@@ -28,8 +109,7 @@ pugi::xml_node GetChild(pugi::xml_node& xnode,
|
||||
return xnode.child((ns + ":" + name).c_str());
|
||||
}
|
||||
|
||||
pugi::xml_node GetChildNoNS(pugi::xml_node& xnode,
|
||||
const std::string& name) {
|
||||
pugi::xml_node GetChildNoNS(pugi::xml_node& xnode, const std::string& name) {
|
||||
pugi::xml_node xchild = xnode.first_child();
|
||||
while (xchild) {
|
||||
std::string child_name = xchild.name();
|
||||
@@ -50,13 +130,28 @@ pugi::xml_node GetChildNoNS(pugi::xml_node& xnode,
|
||||
return pugi::xml_node();
|
||||
}
|
||||
|
||||
void AppendAttr(pugi::xml_node& xnode,
|
||||
const std::string& ns,
|
||||
const std::string& name,
|
||||
const std::string& value) {
|
||||
void AddAttr(pugi::xml_node& xnode,
|
||||
const std::string& ns,
|
||||
const std::string& name,
|
||||
const std::string& value) {
|
||||
std::string ns_name = ns + ":" + name;
|
||||
xnode.append_attribute(ns_name.c_str()) = value.c_str();
|
||||
}
|
||||
|
||||
bool PrettyPrintXml(std::ostream& os,
|
||||
const std::string& xml_string,
|
||||
const char* indent) {
|
||||
pugi::xml_document xdoc;
|
||||
if (!xdoc.load_string(xml_string.c_str())) {
|
||||
os << "Invalid XML" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
xdoc.print(os, indent);
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace xml
|
||||
} // namespace csoap
|
||||
|
||||
+48
-2
@@ -2,13 +2,53 @@
|
||||
#define CSOAP_XML_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#ifdef CSOAP_USE_TINYXML
|
||||
#include "tinyxml/tinyxml.h"
|
||||
#else
|
||||
#include "pugixml/pugixml.hpp"
|
||||
#endif
|
||||
|
||||
// XML utilities.
|
||||
|
||||
namespace csoap {
|
||||
namespace xml {
|
||||
|
||||
#ifdef CSOAP_USE_TINYXML
|
||||
|
||||
// Get the namespace prefix from node name.
|
||||
// Example:
|
||||
// Node name: soapenv:Envelope
|
||||
// NS prefix: soapenv
|
||||
std::string GetNsPrefix(const TiXmlElement* xnode);
|
||||
|
||||
// Append a child with the given name which is prefixed by a namespace.
|
||||
// E.g., AppendChild(xnode, "soapenv", "Envelope") will append a child with
|
||||
// name "soapenv:Envelope".
|
||||
TiXmlElement* AppendChild(TiXmlNode* xnode,
|
||||
const std::string& ns,
|
||||
const std::string& name);
|
||||
|
||||
TiXmlElement* GetChild(TiXmlElement* xnode,
|
||||
const std::string& ns,
|
||||
const std::string& name);
|
||||
|
||||
TiXmlElement* GetChildNoNS(TiXmlElement* xnode, const std::string& name);
|
||||
|
||||
// Add an attribute with the given name which is prefixed by a namespace.
|
||||
void AddAttr(TiXmlElement* xnode,
|
||||
const std::string& ns,
|
||||
const std::string& name,
|
||||
const std::string& value);
|
||||
|
||||
void SetText(TiXmlElement* xnode, const std::string& text);
|
||||
|
||||
bool PrettyPrintXml(std::ostream& os,
|
||||
const std::string& xml_string,
|
||||
const char* indent = " ");
|
||||
|
||||
#else // PugiXml
|
||||
|
||||
// Get the namespace prefix from node name.
|
||||
// Example:
|
||||
// Node name: soapenv:Envelope
|
||||
@@ -29,8 +69,8 @@ pugi::xml_node GetChild(pugi::xml_node& xnode,
|
||||
pugi::xml_node GetChildNoNS(pugi::xml_node& xnode,
|
||||
const std::string& name);
|
||||
|
||||
// Append a attribute with the given name which is prefixed by a namespace.
|
||||
void AppendAttr(pugi::xml_node& xnode,
|
||||
// Add an attribute with the given name which is prefixed by a namespace.
|
||||
void AddAttr(pugi::xml_node& xnode,
|
||||
const std::string& ns,
|
||||
const std::string& name,
|
||||
const std::string& value);
|
||||
@@ -57,6 +97,12 @@ private:
|
||||
std::string* result_;
|
||||
};
|
||||
|
||||
bool PrettyPrintXml(std::ostream& os,
|
||||
const std::string& xml_string,
|
||||
const char* indent = " ");
|
||||
|
||||
#endif // CSOAP_USE_TINYXML
|
||||
|
||||
} // namespace xml
|
||||
} // namespace csoap
|
||||
|
||||
|
||||
Reference in New Issue
Block a user