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
00031
00032
00033
00034
00035
00036
00037
00038
00045
00046 #include "cppdom.h"
00047 #include "xmlparser.h"
00048
00049
00050 namespace cppdom
00051 {
00052
00053
00054 XMLError::XMLError(XMLErrorCode code)
00055 : mErrorCode(code)
00056 {}
00057
00058 XMLErrorCode XMLError::getError() const
00059 {
00060 return mErrorCode;
00061 }
00062
00063 void XMLError::getStrError(std::string& error) const
00064 {
00065
00066 #define XMLERRORCODE(x,y) case x: err = y; break;
00067
00068 const char *err;
00069 switch(mErrorCode)
00070 {
00071 XMLERRORCODE(xml_unknown,"unspecified or unknown error");
00072 XMLERRORCODE(xml_instream_error,"error in the infile stream");
00073 XMLERRORCODE(xml_opentag_expected,"expected an open tag literal '<'");
00074 XMLERRORCODE(xml_opentag_cdata_expected,"expected a '<' or cdata");
00075 XMLERRORCODE(xml_closetag_expected,"expected an '>' closing tag literal");
00076 XMLERRORCODE(xml_pi_doctype_expected,"expected a processing instruction or doctype tag");
00077 XMLERRORCODE(xml_tagname_expected,"expected a tag name after '<' or '</'");
00078 XMLERRORCODE(xml_closetag_slash_expected,"expected a '/' after closing tag literal '<'");
00079 XMLERRORCODE(xml_tagname_close_mismatch,"tag name from start and end tag mismatch");
00080 XMLERRORCODE(xml_attr_equal_expected,"expected '=' after attribute name");
00081 XMLERRORCODE(xml_attr_value_expected,"expected value after 'a' in attribute");
00082 XMLERRORCODE(xml_save_invalid_nodetype,"invalid nodetype encountered while saving");
00083 XMLERRORCODE(xml_filename_invalid,"invalid file name");
00084 XMLERRORCODE(xml_file_access,"could not access file");
00085 XMLERRORCODE(xml_dummy,"dummy error code (this error should never been seen)");
00086 }
00087 error.assign(err);
00088 #undef XMLERRORCODE
00089 }
00090
00091 std::string XMLError::getString() const
00092 {
00093 std::string err;
00094 getStrError(err);
00095 return err;
00096 }
00097
00098 std::string XMLError::getInfo() const
00099 {
00100 return "unknown error";
00101 }
00102
00103
00104
00105 XMLLocation::XMLLocation()
00106 {
00107 reset();
00108 }
00109
00110 int XMLLocation::getLine() const
00111 {
00112 return mLine;
00113 }
00114
00115 int XMLLocation::getPos() const
00116 {
00117 return mPos;
00118 }
00119
00120 void XMLLocation::step(int chars)
00121 {
00122 mPos += chars;
00123 }
00124
00125 void XMLLocation::newline()
00126 {
00127 ++mLine;
00128 mPos = 1;
00129 }
00130
00131 void XMLLocation::reset()
00132 {
00133 mLine = mPos = 0;
00134 }
00135
00136
00137
00138 XMLContext::XMLContext()
00139 : mEventHandler(new XMLEventHandler)
00140 {
00141 mInit = false;
00142 mNextHandle = 0;
00143 mHandleEvents = false;
00144 }
00145
00146 XMLContext::~XMLContext()
00147 {
00148 }
00149
00150 std::string XMLContext::getEntity(const std::string& entName)
00151 {
00152 if (!mInit)
00153 {
00154 initContext();
00155 }
00156
00157 XMLEntityMap::const_iterator iter = mEntities.find(entName);
00158 return (iter == mEntities.end() ? entName : iter->second);
00159 }
00160
00161 std::string XMLContext::getTagname(XMLTagNameHandle handle)
00162 {
00163 if (!mInit)
00164 {
00165 initContext();
00166 }
00167 XMLTagNameMap::const_iterator iter = mTagNames.find(handle);
00168
00169 std::string empty("");
00170 return (iter == mTagNames.end() ? empty : iter->second);
00171 }
00172
00173 XMLTagNameHandle XMLContext::insertTagname(const std::string& tagName)
00174 {
00175 if (!mInit)
00176 {
00177 initContext();
00178 }
00179
00180
00181
00182
00183 XMLTagNameMap::const_iterator iter,stop;
00184 iter = mTagNames.begin();
00185 stop = mTagNames.end();
00186
00187 for(; iter!=stop; ++iter)
00188 {
00189 if (iter->second == tagName)
00190 {
00191 return iter->first;
00192 }
00193 }
00194
00195
00196 XMLTagNameMap::value_type keyvaluepair(mNextHandle, tagName);
00197 mTagNames.insert(keyvaluepair);
00198
00199 return mNextHandle++;
00200 }
00201
00202 XMLLocation& XMLContext::getLocation()
00203 {
00204 return mLocation;
00205 }
00206
00207 void XMLContext::initContext()
00208 {
00209 mInit = true;
00210 }
00211
00212 void XMLContext::setEventHandler(XMLEventHandlerPtr ehptr)
00213 {
00214 mEventHandler = ehptr;
00215 mHandleEvents = true;
00216 }
00217
00218 XMLEventHandler& XMLContext::getEventHandler()
00219 {
00220 return *mEventHandler.get();
00221 }
00222
00223 bool XMLContext::handleEvents() const
00224 {
00225 return mHandleEvents;
00226 }
00227
00228
00229
00230
00231 XMLAttribute::XMLAttribute()
00232 : mData("")
00233 {}
00234
00235 XMLAttribute::XMLAttribute(const XMLAttribute& attr)
00236 : mData(attr.mData)
00237 {}
00238
00239 XMLAttribute::XMLAttribute(const std::string& val)
00240 : mData(val)
00241 {}
00242
00243 const std::string& XMLAttribute::getString() const
00244 {
00245 return mData;
00246 }
00247
00248 XMLAttribute::operator std::string() const
00249 {
00250 return getString();
00251 }
00252
00253
00254
00255 XMLAttributes::XMLAttributes()
00256 {}
00257
00258 std::string XMLAttributes::get(const std::string& key) const
00259 {
00260 XMLAttributes::const_iterator iter;
00261
00262
00263 iter = find(key);
00264 std::string empty("");
00265 return ((iter == end()) ? empty : iter->second);
00266 }
00267
00268 void XMLAttributes::set(const std::string& key, const std::string& value)
00269 {
00270 XMLAttributes::iterator iter;
00271
00272
00273 iter = find(key);
00274 if (iter != end())
00275 {
00276 (*iter).second = value;
00277 }
00278 else
00279 {
00280
00281 XMLAttributes::value_type pa(key,value);
00282 insert(pa);
00283 }
00284 }
00285
00286 bool XMLAttributes::has(const std::string& key) const
00287 {
00288 XMLAttributes::const_iterator iter;
00289
00290
00291 iter = find(key);
00292 return (iter != end());
00293 }
00294
00295
00296
00297
00298 XMLNode::XMLNode()
00299 : mNodeType(xml_nt_node), mParent(0)
00300 {}
00301
00302 XMLNode::XMLNode(XMLContextPtr ctx)
00303 : mContext(ctx), mNodeType(xml_nt_node), mParent(0)
00304 {}
00305
00306 XMLNode::XMLNode(const XMLNode& node)
00307 : mNodeNameHandle(node.mNodeNameHandle)
00308 , mContext(node.mContext)
00309 , mNodeType(node.mNodeType)
00310 , mAttributes(node.mAttributes)
00311 , mCdata(node.mCdata)
00312 , mNodeList(node.mNodeList)
00313 , mParent(node.mParent)
00314 {}
00315
00316 XMLNode::~XMLNode()
00317 {
00318 for (XMLNodeList::iterator i = mNodeList.begin(); i != mNodeList.end(); ++i)
00319 {
00320 (*i)->mParent = NULL;
00321 }
00322 }
00323
00324 XMLNode& XMLNode::operator=(const XMLNode& node)
00325 {
00326 mNodeNameHandle = node.mNodeNameHandle;
00327 mContext = node.mContext;
00328 mNodeType = node.mNodeType;
00329 mAttributes = node.mAttributes;
00330 mCdata = node.mCdata;
00331 mNodeList = node.mNodeList;
00332 mParent = node.mParent;
00333 return *this;
00334 }
00335
00336 XMLNodeType XMLNode::getType() const
00337 {
00338 return mNodeType;
00339 }
00340
00341 std::string XMLNode::getName()
00342 {
00343 return mContext->getTagname(mNodeNameHandle);
00344 }
00345
00346 XMLAttributes& XMLNode::getAttrMap()
00347 {
00348 return mAttributes;
00349 }
00350
00351 XMLAttribute XMLNode::getAttribute(const std::string& name) const
00352 {
00353 return mAttributes.get(name);
00354 }
00355
00356 bool XMLNode::hasAttribute(const std::string& name) const
00357 {
00358 return mAttributes.has(name);
00359 }
00360
00361 const std::string& XMLNode::getCdata()
00362 {
00363 return mCdata;
00364 }
00365
00366 void XMLNode::setType(XMLNodeType type)
00367 {
00368 mNodeType = type;
00369 }
00370
00371 void XMLNode::setName(const std::string& name)
00372 {
00373 mNodeNameHandle = mContext->insertTagname(name);
00374 }
00375
00376 void XMLNode::setCdata(const std::string& cdata)
00377 {
00378 mCdata = cdata;
00379 }
00380
00381 void XMLNode::setAttribute(const std::string& attr, const XMLAttribute& value)
00382 {
00383 mAttributes.set(attr, value.getString());
00384 }
00385
00386 void XMLNode::addChild(XMLNodePtr& node)
00387 {
00388 node->mParent = this;
00389 mNodeList.push_back(node);
00390 }
00391
00392 bool XMLNode::removeChild(XMLNodePtr& node)
00393 {
00394 std::cout << "cppdom::XMLNode::removeChild: not implemented\n";
00395 return false;
00396 }
00397
00398 bool XMLNode::removeChild(std::string& childName)
00399 {
00400 std::cout << "cppdom::XMLNode::removeChild: not implemented\n";
00401 return false;
00402 }
00403
00404 bool XMLNode::removeChildren(std::string& childName)
00405 {
00406 std::cout << "cppdom::XMLNode::removeChildren: not implemented\n";
00407 return false;
00408 }
00409
00410 XMLNodeList& XMLNode::getChildren()
00411 {
00412 return mNodeList;
00413 }
00414
00416 XMLNodePtr XMLNode::getChild(const std::string& name)
00417 {
00418
00419 XMLNodeList::const_iterator iter;
00420
00421
00422 for(iter = mNodeList.begin(); iter != mNodeList.end(); ++iter)
00423 {
00424 XMLNodePtr np = (*iter);
00425 if (np->getName() == name)
00426 {
00427 return np;
00428 }
00429 }
00430
00431
00432 return XMLNodePtr();
00433 }
00434
00435 XMLNodeList XMLNode::getChildren(const std::string& name)
00436 {
00437 XMLNodeList result(0);
00438 XMLNodeList::const_iterator iter;
00439
00440
00441 for(iter = mNodeList.begin(); iter != mNodeList.end(); ++iter)
00442 {
00443 if ((*iter)->getName() == name)
00444 {
00445 result.push_back(*iter);
00446 }
00447 }
00448
00449 return result;
00450 }
00451
00452 XMLNodeList XMLNode::getChildren(const char* name)
00453 {
00454 return getChildren(std::string(name));
00455 }
00456
00457 XMLNode* XMLNode::getParent() const
00458 {
00459 return mParent;
00460 }
00461
00463 void XMLNode::load(std::istream& in, XMLContextPtr& context)
00464 {
00465 XMLParser parser(in, context->getLocation());
00466 parser.parseNode(*this, context);
00467 }
00468
00470 void XMLNode::save(std::ostream& out, int indent)
00471 {
00472
00473 for(int i=0; i<indent; ++i)
00474 {
00475 out << ' ';
00476 }
00477
00478
00479 if (mNodeType == xml_nt_cdata)
00480 {
00481 out << mCdata.c_str() << std::endl;
00482 return;
00483 }
00484
00485
00486 out << '<' << mContext->getTagname(mNodeNameHandle);
00487
00488
00489 XMLAttributes::const_iterator iter, stop;
00490 iter = mAttributes.begin();
00491 stop = mAttributes.end();
00492
00493 for(; iter!=stop; ++iter)
00494 {
00495 XMLAttributes::value_type attr = *iter;
00496 out << ' ' << attr.first << '=' << '\"' << attr.second << '\"';
00497 }
00498
00499
00500 switch(mNodeType)
00501 {
00502 case xml_nt_node:
00503 {
00504 out << '>' << std::endl;
00505
00506
00507 XMLNodeList::const_iterator iter,stop;
00508 iter = mNodeList.begin();
00509 stop = mNodeList.end();
00510
00511 for(; iter!=stop; ++iter)
00512 {
00513 (*iter)->save(out, indent+1);
00514 }
00515
00516
00517 for(int i=0;i<indent;i++)
00518 {
00519 out << ' ';
00520 }
00521
00522
00523 out << '<' << '/'
00524 << mContext->getTagname(mNodeNameHandle) << '>' << std::endl;
00525 }
00526 break;
00527 case xml_nt_leaf:
00528
00529 out << '/' << '>' << std::endl;
00530 break;
00531 default:
00532
00533 throw XMLError(xml_save_invalid_nodetype);
00534 }
00535 }
00536
00537 XMLContextPtr XMLNode::getContext()
00538 {
00539 return mContext;
00540 }
00541
00542
00543
00544
00545 XMLDocument::XMLDocument()
00546 {
00547 mNodeType = xml_nt_document;
00548 }
00549
00550 XMLDocument::XMLDocument(XMLContextPtr context)
00551 : XMLNode(context)
00552 {
00553 mNodeType = xml_nt_document;
00554 }
00555
00556 XMLNodeList& XMLDocument::getPiList()
00557 {
00558 return mProcInstructions;
00559 }
00560
00561 XMLNodeList& XMLDocument::getDtdList()
00562 {
00563 return mDtdRules;
00564 }
00565
00567 void XMLDocument::load(std::istream& in, XMLContextPtr& context)
00568 {
00569 XMLParser parser(in, context->getLocation());
00570 parser.parseDocument(*this, context);
00571 }
00572
00576 void XMLDocument::save(std::ostream& out)
00577 {
00578
00579 XMLNodeList::const_iterator iter, stop;
00580 iter = mProcInstructions.begin();
00581 stop = mProcInstructions.end();
00582
00583 for(; iter!=stop; ++iter)
00584 {
00585 XMLNodePtr np = *iter;
00586
00587
00588 out << "<?" << np->getName();
00589
00590
00591 XMLAttributes::const_iterator aiter, astop;
00592 aiter = mAttributes.begin();
00593 astop = mAttributes.end();
00594
00595 for(; aiter!=astop; ++aiter)
00596 {
00597 XMLAttributes::value_type attr = *aiter;
00598 out << ' ' << attr.first << '=' << '\"' << attr.second << '\"';
00599 }
00600
00601 out << "?>" << std::endl;
00602 }
00603
00604
00605
00606
00607
00608
00609
00610 (*mNodeList.begin())->save(out, 0);
00611 }
00612
00613 void XMLDocument::loadFile(const std::string& filename) throw(XMLError)
00614 {
00615 std::ifstream in;
00616 in.open(filename.c_str(), std::ios::in);
00617
00618 if (! in.good())
00619 {
00620 throw XMLError(xml_filename_invalid);
00621 }
00622
00623 load(in, mContext);
00624 in.close();
00625 }
00626
00627 void XMLDocument::saveFile(const std::string& filename)
00628 {
00629 std::ofstream out;
00630 out.open(filename.c_str(), std::ios::in | std::ios::out);
00631 this->save(out);
00632 out.close();
00633 }
00634 }