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
00034 #ifndef XML_FILE_OUTPUT_INCLUDED
00035 #define XML_FILE_OUTPUT_INCLUDED
00036
00037 #include <vector>
00038 #include "UnicodeString.h"
00039
00040 namespace hwdet
00041 {
00042
00044 #ifdef UNICODE
00045 const Char DefaultEncoding[] = TXT("UTF-16");
00046 #else
00047 #ifdef _WINDOWS
00048 const Char DefaultEncoding[] = TXT("WINDOWS-1252");
00049 #else
00050 const Char DefaultEncoding[] = TXT("US-ASCII");
00051 #endif
00052 #endif
00053
00059 template< typename T > String inline ConvertToXMLString(const T &value)
00060 {
00061 StringStream stream;
00062
00063 stream << value;
00064
00065 return stream.str();
00066 }
00067
00073 String inline ConvertToXMLString(const String &value)
00074 {
00075 StringStream stream;
00076
00077 const String chars = TXT("&\'\"<>");
00078 const String reps[] = {TXT("&"), TXT("'"), TXT("""), TXT("<"), TXT(">")};
00079
00080 String::const_iterator end = value.end();
00081
00082 for (String::const_iterator it = value.begin(); it != end; ++it)
00083 {
00084 size_t index = chars.find(*it);
00085 if (index == chars.npos)
00086 {
00087 stream << (Char) *it;
00088 }
00089 else
00090 {
00091 stream << reps[index];
00092 }
00093 }
00094
00095 return stream.str();
00096 }
00097
00102 class XMLElement
00103 {
00104 public:
00109 XMLElement(void) :
00110 name(TXT("(undefined)")),
00111 depth(0),
00112 parent(NULL)
00113 {
00114 }
00115
00120 XMLElement(const Char *elem_name) :
00121 name(elem_name),
00122 depth(0),
00123 parent(NULL)
00124 {
00125 }
00126
00131 XMLElement(const String &elem_name) :
00132 name(elem_name),
00133 depth(0),
00134 parent(NULL)
00135 {
00136 }
00137
00142 virtual ~XMLElement(void)
00143 {
00144 std::vector< XMLElement * >::const_iterator end = nodes.end();
00145
00146 for (std::vector< XMLElement * >::const_iterator it = nodes.begin(); it != end; ++it)
00147 {
00148 delete *it;
00149 }
00150 }
00151
00156 virtual String GetNodeName(void) const
00157 {
00158 return name;
00159 }
00160
00167 void AddSubNode(XMLElement *new_node)
00168 {
00169 if (new_node == NULL)
00170 {
00171 return;
00172 }
00173
00174 new_node->SetNodeParent(this);
00175 nodes.push_back(new_node);
00176 }
00177
00183 XMLElement *GetSubNode(const size_t index) const
00184 {
00185 if (index < nodes.size())
00186 {
00187 return nodes[index];
00188 }
00189 else
00190 {
00191 return NULL;
00192 }
00193 }
00194
00199 size_t GetSubNodeCount(void) const
00200 {
00201 return nodes.size();
00202 }
00203
00210 virtual String GetNodeValueString(void)
00211 {
00212 StringStream stream;
00213
00214 std::vector< XMLElement * >::const_iterator end = nodes.end();
00215
00216 for (std::vector< XMLElement * >::const_iterator it = nodes.begin(); it != end; ++it)
00217 {
00218 (*it)->AppendToStream(stream);
00219 }
00220
00221 return stream.str();
00222 }
00223
00228 virtual void AppendToStream(OStream &stream) const
00229 {
00230 for (size_t i = 0; i < depth; ++i)
00231 {
00232 stream << TXT("\t");
00233 }
00234
00235 stream << TXT("<") << GetNodeName() << TXT(">") << std::endl;
00236
00237 std::vector< XMLElement * >::const_iterator end = nodes.end();
00238 for (std::vector< XMLElement * >::const_iterator it = nodes.begin(); it != end; ++it)
00239 {
00240 (*it)->AppendToStream(stream);
00241 }
00242
00243 for (size_t i = 0; i < depth; ++i)
00244 {
00245 stream << TXT("\t");
00246 }
00247
00248 stream << TXT("</") << GetNodeName() << TXT(">") << std::endl;
00249 }
00250
00251 protected:
00252
00254 String name;
00255
00257 std::vector< XMLElement* > nodes;
00258
00260 size_t depth;
00261
00263 XMLElement *parent;
00264
00271 void SetNodeDepth(size_t nd)
00272 {
00273 depth = nd;
00274 std::vector< XMLElement * >::iterator end = nodes.end();
00275
00276 for (std::vector< XMLElement * >::iterator it = nodes.begin(); it != end; ++it)
00277 {
00278 (*it)->SetNodeDepth(depth + 1);
00279 }
00280 }
00281
00288 void SetNodeParent(XMLElement *e)
00289 {
00290 parent = e;
00291
00292 if (e != NULL)
00293 {
00294 SetNodeDepth(e->depth + 1);
00295 }
00296 else
00297 {
00298 SetNodeDepth(0);
00299 }
00300 }
00301 };
00302
00305 template< typename T >
00306 class XMLValueElement : public XMLElement
00307 {
00308 public:
00314 XMLValueElement(const Char *elem_name, const T elem_value) :
00315 XMLElement(elem_name),
00316 value(elem_value)
00317 {
00318 }
00319
00325 XMLValueElement(const String &elem_name, const T elem_value) :
00326 XMLElement(elem_name),
00327 value(elem_value)
00328 {
00329 }
00330
00333 virtual ~XMLValueElement(void)
00334 {
00335 }
00336
00341 T GetNodeValue(void) const
00342 {
00343 return value;
00344 }
00345
00350 void SetNodeValue(T new_value)
00351 {
00352 value = new_value;
00353 }
00354
00359 String GetNodeValueString(void) const
00360 {
00361 return ConvertToXMLString(value);
00362 }
00363
00368 virtual void AppendToStream(OStream &stream) const
00369 {
00370 for (size_t i = 0; i < depth; ++i)
00371 {
00372 stream << TXT("\t");
00373 }
00374
00375 stream << TXT("<") << GetNodeName() << TXT(">") << GetNodeValueString() <<
00376 TXT("</") << GetNodeName() << TXT(">") << std::endl;
00377 }
00378
00379 protected:
00381 T value;
00382 };
00383
00386 class XMLOutputFile
00387 {
00388 public:
00395 XMLOutputFile(const Char *enc = NULL) :
00396 root_node(NULL),
00397 encoding(TXT(""))
00398 {
00399 if (enc != NULL)
00400 {
00401 encoding = String(enc);
00402 }
00403 }
00404
00412 XMLOutputFile(XMLElement *root_elem, const Char *enc = DefaultEncoding) :
00413 root_node(root_elem),
00414 encoding(enc)
00415 {
00416 }
00417
00422 ~XMLOutputFile(void)
00423 {
00424 }
00425
00431 bool Write(OStream &stream) const
00432 {
00433 if (encoding != String(TXT("")))
00434 {
00435 stream << TXT("<?xml version=\"1.0\" encoding=\"") << encoding << TXT("\"?>") << std::endl;
00436 }
00437 else
00438 {
00439 stream << TXT("<?xml version=\"1.0\"?>") << std::endl;
00440 }
00441
00442 root_node->AppendToStream(stream);
00443
00444 return true;
00445 }
00446
00454 bool Write(String file_name) const
00455 {
00456 if (root_node == NULL)
00457 {
00458 return false;
00459 }
00460
00461 OFStream file;
00462
00463 #if defined(_MSC_VER) && (_MSC_VER < 1400) && defined(UNICODE) && defined(_WINDOWS)
00464
00465
00466 file.open(Win_UnicodeToANSI(file_name).c_str(), std::ios_base::out);
00467 #else
00468 file.open(file_name.c_str(), std::ios_base::out);
00469 #endif
00470
00471 if (file.is_open())
00472 {
00473 if (encoding != String(TXT("")))
00474 {
00475 file << TXT("<?xml version=\"1.0\" encoding=\"") << encoding << TXT("\"?>") << std::endl;
00476 }
00477 else
00478 {
00479 file << TXT("<?xml version=\"1.0\"?>") << std::endl;
00480 }
00481
00482 root_node->AppendToStream(file);
00483 file.close();
00484
00485 return true;
00486 }
00487
00488 return false;
00489 }
00490
00495 void SetRootNode(XMLElement *elem)
00496 {
00497 root_node = elem;
00498 }
00499
00502 void ClearRootNode(void)
00503 {
00504 delete root_node;
00505 root_node = NULL;
00506 }
00507
00512 String GetEncoding(void) const
00513 {
00514 return encoding;
00515 }
00516
00517 private:
00519 XMLElement *root_node;
00520
00522 String encoding;
00523 };
00524
00525 }
00526
00527 #endif