Add an option to use tinyxml instead of pugixml.

This commit is contained in:
Adam Gu
2017-06-07 17:18:21 +08:00
parent cff90c15fb
commit ab2c6fce35
19 changed files with 6595 additions and 32 deletions
+2
View File
@@ -1,5 +1,7 @@
#include "csoap/common.h"
#include "boost/lexical_cast.hpp"
namespace csoap {
////////////////////////////////////////////////////////////////////////////////
-9
View File
@@ -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_;
}
+1
View File
@@ -2,6 +2,7 @@
#include "boost/bind.hpp"
#include "boost/algorithm/string.hpp"
#include "boost/lexical_cast.hpp"
#include "csoap/common.h"
+43 -6
View File
@@ -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
+43 -5
View File
@@ -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
View File
@@ -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
View File
@@ -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