XmlElement.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "config.h"
00031
00032 #include "XmlElement.hpp"
00033
00034 #include <string>
00035 #include <sstream>
00036
00037 #include <libxml/xmlmemory.h>
00038 #include <libxml/parser.h>
00039
00040 #include <Exception.hpp>
00041
00042 #include "XmlItem.hpp"
00043
00044 using namespace mermaid::support::xml;
00045 using std::string;
00046 using std::stringstream;
00047 using mermaid::support::errorhandling::Exception;
00048
00049
00050
00051 XmlElement::XmlElement()
00052 {
00053 name_ = string ("UNNAMED");
00054 charData_ = XmlCharDataVector();
00055 childrenElements_ = XmlElementVector();
00056 attributes_ = XmlAttributeVector();
00057 items_ = XmlItemVector();
00058 }
00059
00060
00061
00062 XmlElement::XmlElement (const XmlElement& e)
00063 {
00064 copyFrom (e);
00065 }
00066
00067
00068
00069 XmlElement::XmlElement (string xml)
00070 {
00071 xmlNodePtr rootElementNode;
00072
00073 xmlParserCtxtPtr parserCtxtPtr = xmlNewParserCtxt();
00074 xmlDocPtr docPtr = xmlCtxtReadMemory (parserCtxtPtr,
00075 xml.data(),
00076 xml.size(),
00077 NULL,
00078 NULL,
00079 0);
00080
00081 if ( (parserCtxtPtr->wellFormed == 0) || (docPtr == NULL)) {
00082 XmlElement();
00083 throw Exception ("XmlElement::XmlElement(string xml) : unable to "
00084 "build from string: \"" + xml + "\"");
00085 }
00086
00087 rootElementNode = xmlDocGetRootElement (docPtr);
00088
00089 if (rootElementNode == NULL) {
00090 xmlFreeDoc (docPtr);
00091 XmlElement();
00092 throw Exception ("XmlElement::XmlElement(string xml) : unable to "
00093 "build from string: \"" + xml + "\"");
00094 }
00095 this->buildFromLibxml2Node (rootElementNode);
00096
00097 if (parserCtxtPtr != NULL) {
00098 xmlFreeParserCtxt (parserCtxtPtr);
00099 }
00100
00101 if (docPtr != NULL) {
00102 xmlFreeDoc (docPtr);
00103 }
00104 }
00105
00106
00107
00108 XmlElement::XmlElement (xmlNodePtr node)
00109 {
00110 this->buildFromLibxml2Node (node);
00111 }
00112
00113
00114
00115 void XmlElement::buildFromLibxml2Node (xmlNodePtr node)
00116 {
00117
00118 name_ = string ( (char*) node->name);
00119
00120
00121 xmlNodePtr child = node->children;
00122 while (child != NULL) {
00123 if (child->type == XML_ELEMENT_NODE) {
00124 shared_ptr<XmlElement> e =
00125 shared_ptr<XmlElement> (new XmlElement (child));
00126 if (e == false) {
00127 throw Exception ("XmlElement::buildFromLibxml2Node : unable to "
00128 "create XmlElement");
00129 }
00130 childrenElements_.push_back (e);
00131 items_.push_back (static_cast<XmlItem*> (e.get()));
00132
00133 }
00134 else if ( (child->type == XML_TEXT_NODE)
00135 || (child->type == XML_CDATA_SECTION_NODE)) {
00136 shared_ptr<XmlCharData> c =
00137 shared_ptr<XmlCharData> (new XmlCharData ( (char*) child->content));
00138 if (c == false) {
00139 throw Exception ("XmlElement::buildFromLibxml2Node : unable to "
00140 "create XmlCharData");
00141 }
00142 charData_.push_back (c);
00143 items_.push_back (static_cast<XmlItem*> (c.get()));
00144
00145 }
00146 child = child->next;
00147 }
00148
00149
00150 xmlAttrPtr attr = node->properties;
00151 while ( (attr != NULL)) {
00152 if (attr->type == XML_ATTRIBUTE_NODE) {
00153 attributes_.push_back (
00154 shared_ptr<XmlAttribute> (new XmlAttribute (attr)));
00155 }
00156 attr = attr->next;
00157 }
00158 }
00159
00160
00161
00162 XmlElement::~XmlElement()
00163 {
00164 cleanUp();
00165 }
00166
00167
00168
00169 XmlElement * XmlElement::clone()
00170 {
00171 return new XmlElement (*this);
00172 }
00173
00174
00175
00176 XmlElement& XmlElement::operator= (const XmlElement & e)
00177 {
00178
00179 if (this != &e) {
00180 cleanUp();
00181 copyFrom (e);
00182 }
00183 return *this;
00184 }
00185
00186
00187
00188 const string XmlElement::getName() const
00189 {
00190 return name_;
00191 }
00192
00193
00194
00195 XmlCharDataVector XmlElement::getCharData()
00196 {
00197 return charData_;
00198 }
00199
00200
00201
00202 shared_ptr<XmlCharData> XmlElement::getFirstNonBlankCharData()
00203 {
00204 XmlCharDataVector vector = this->getCharData();
00205
00206 for (XmlCharDataVector::iterator it = vector.begin();
00207 it != vector.end();
00208 it++) {
00209 shared_ptr<XmlCharData> xc = *it;
00210
00211 if (!xc->isBlank()) {
00212 return xc;
00213 }
00214 }
00215
00216 return shared_ptr<XmlCharData>();
00217 }
00218
00219
00220
00221 XmlElementVector XmlElement::getChildrenElements()
00222 {
00223 return childrenElements_;
00224 }
00225
00226
00227
00228 const XmlAttributeVector XmlElement::getAttributes() const
00229 {
00230 return attributes_;
00231 }
00232
00233
00234
00235 XmlElement::operator string() const
00236 {
00237 stringstream ss;
00238 ss << "<";
00239 ss << this->getName();
00240
00241 XmlAttributeVector attributes = this->getAttributes();
00242
00243 if (attributes.size() > 0) {
00244 ss << " ";
00245 XmlAttributeVector::iterator it;
00246
00247 for (it = attributes.begin(); it != attributes.end(); it++) {
00248 shared_ptr<XmlAttribute> a = *it;
00249 ss << a->getName();
00250 ss << "=\"";
00251 ss << a->getValue();
00252 ss << "\" ";
00253 }
00254 }
00255
00256 ss << ">";
00257
00258 XmlItemVector::const_iterator it;
00259
00260 for (it = items_.begin(); it != items_.end(); it++) {
00261 XmlItem * i = *it;
00262 ss << ( (string) *i);
00263 }
00264
00265 ss << "</";
00266 ss << this->getName();
00267 ss << ">";
00268
00269 return ss.str();
00270 }
00271
00272
00273
00274 const bool XmlElement::isXmlElement() const
00275 {
00276 return true;
00277 }
00278
00279
00280
00281 void XmlElement::copyFrom (const XmlElement& e)
00282 {
00283 name_ = e.name_;
00284
00285
00286 for (XmlItemVector::const_iterator iit = e.items_.begin();
00287 iit != e.items_.end();
00288 iit++) {
00289 XmlItem * i = *iit;
00290 if (i->isXmlElement()) {
00291 XmlElement * xe = (XmlElement*) i;
00292 XmlElement * ne = new XmlElement (*xe);
00293 this->childrenElements_.push_back (shared_ptr<XmlElement> (ne));
00294 this->items_.push_back ( (XmlItem*) ne);
00295 }
00296 else if (i->isXmlCharData()) {
00297 XmlCharData * xc = (XmlCharData*) i;
00298 XmlCharData * nc = new XmlCharData (*xc);
00299 this->charData_.push_back (shared_ptr<XmlCharData> (nc));
00300 this->items_.push_back ( (XmlItem*) nc);
00301 }
00302 else {
00303 throw Exception ("XmlElement::copyFrom : got unidentifiable item");
00304 }
00305 }
00306
00307
00308 XmlAttributeVector::const_iterator ait;
00309 for (ait = e.attributes_.begin(); ait != e.attributes_.end(); ait++) {
00310 shared_ptr<XmlAttribute> a = *ait;
00311 XmlAttribute * na = new XmlAttribute (*a);
00312 attributes_.push_back (shared_ptr<XmlAttribute> (na));
00313 }
00314 }
00315
00316
00317
00318 void XmlElement::cleanUp()
00319 {
00320 name_ = string ("UNNAMED");
00321 charData_ = XmlCharDataVector();
00322 childrenElements_ = XmlElementVector();
00323 attributes_ = XmlAttributeVector();
00324 items_ = XmlItemVector();
00325 }