| 58 | | }; |
| 59 | | |
| 60 | | //! The only global instance of the GlobalXercesConnector class |
| 61 | | extern const GlobalXercesConnector XMLConnector; |
| | 76 | |
| | 77 | //! The only global instance of the XercesConnector class |
| | 78 | // potrebujeme inicializaci hned v okamziku zavolani!! |
| | 79 | static XercesConnector& instance() |
| | 80 | { |
| | 81 | static XercesConnector gxc; |
| | 82 | return gxc; |
| | 83 | }; |
| | 84 | }; |
| | 85 | |
| | 86 | class BindingFrame |
| | 87 | { |
| | 88 | public: |
| | 89 | // nacpe na prislusne pointery, kdyztak da NULL |
| | 90 | virtual void AssemblyBindedData( DOMElement &element ) = 0; |
| | 91 | |
| | 92 | // uvolneni pameti po slozeni objektu, tj. lze jedine po AssemblyBD |
| | 93 | virtual void ReleaseUsedMemory() = 0; |
| | 94 | |
| | 95 | // vrati bool, pokud se povedlo rozebrat a naplnit element |
| | 96 | // nebude tu nahodou jeste ten help - string?? |
| | 97 | virtual bool DisassemblyBindedData( DOMElement &element ) = 0; |
| | 98 | }; |
| 73 | | //! Name which identifies the attribute among others related to the same XML-tag, |
| 74 | | //! must be unique within its context! |
| 75 | | XMLCh* const transcodedName; |
| 76 | | |
| 77 | | public: |
| 78 | | //! Type definition of mapping which transforms names to the related attributes |
| 79 | | typedef map<const XMLCh* const, Attribute* const, GlobalXercesConnector::Comparator> MappedAttributes; |
| 80 | | |
| 81 | | //! The only constructor which fills the transcodedName attribute |
| 82 | | Attribute( const string name ); |
| 83 | | //! Destructor |
| 84 | | ~Attribute(); |
| 85 | | |
| 86 | | //! Set accessor to this attribute converting input string into a properly-typed value |
| 87 | | virtual void Set( const string str ) = 0; |
| 88 | | //! Get accessor converting stored value into a string |
| 89 | | virtual const string Get() = 0; |
| 90 | | //! This method is the key method to connect the attribute to the related UI element |
| 91 | | void Attach( MappedAttributes &externalAttributes); |
| 92 | | //! This method add and DOMAttribute node to the DOMElement passed as an argument |
| 93 | | void FillAttribute(DOMElement &element); |
| 94 | | }; |
| 95 | | |
| 96 | | /*! |
| 97 | | @brief Class encapsulating all the necessary stuff to work with the double attribute |
| 98 | | */ |
| 99 | | class DoubleAttribute: public Attribute |
| 100 | | { |
| 101 | | public: |
| 102 | | double value; |
| 103 | | DoubleAttribute( const string name); |
| 104 | | void Set( const string str ); |
| 105 | | const string Get(); |
| 106 | | }; |
| 107 | | |
| 108 | | |
| 109 | | /*! |
| 110 | | @brief Class encapsulating all the necessary stuff to work with an int attribute |
| 111 | | */ |
| 112 | | class IntAttribute : public Attribute |
| 113 | | { |
| 114 | | public: |
| 115 | | int value; |
| 116 | | IntAttribute( const string name ); |
| 117 | | void Set( const string str ); |
| 118 | | const string Get(); |
| 119 | | }; |
| 120 | | |
| 121 | | /*! |
| 122 | | @brief Class encapsulating all the necessary stuff to work with a string attribute |
| 123 | | */ |
| 124 | | class StringAttribute : public Attribute |
| 125 | | { |
| 126 | | public: |
| 127 | | string value; |
| 128 | | StringAttribute( const string name ); |
| 129 | | void Set( const string str ); |
| 130 | | const string Get(); |
| 131 | | }; |
| 132 | | |
| 133 | | /*! |
| 134 | | @brief UserInfoCore class is for internal purposes only. Use UserInfo<T> instead. |
| 135 | | |
| 136 | | The raison d'etre of this class is to allow pointers to (the main part of) |
| 137 | | UserInfo<T> objects even for different generic types. |
| 138 | | */ |
| 139 | | class UserInfoCore |
| 140 | | { |
| 141 | | public: |
| 142 | | //! Fills internal attributes and descendant elements according DOMElement |
| 143 | | virtual void ParseElement(DOMElement *element) = 0; |
| 144 | | |
| 145 | | //! Fills DOMElement according internal attributes and descendant elements |
| 146 | | virtual void FillElement(DOMElement &element) = 0; |
| 147 | | }; |
| 148 | | |
| 149 | | /*! |
| 150 | | @brief The main user info template class |
| 151 | | |
| 152 | | You should derive this class whenever you need new UserInfo. |
| 153 | | */ |
| 154 | | template<typename T> class UserInfo : public UserInfoCore |
| 155 | | { |
| 156 | | private: |
| 157 | | //! Name which identifies the element among others related to the same XML-tag, |
| 158 | | //! must be unique within its context! |
| 159 | | XMLCh* transcodedName; |
| | 111 | //! Type definition of mapping which transforms type names to the related user infors |
| | 112 | typedef map< const string, UserInfo*> MappedName2UI; |
| 161 | | //! Type definition of mapping which transforms names to the related elements |
| 162 | | typedef map<const XMLCh* const, UserInfoCore* const, GlobalXercesConnector::Comparator> MappedElements; |
| 163 | | |
| 164 | | protected: |
| 165 | | //! MappiLength of the output vector |
| 166 | | MappedElements elements; |
| 167 | | //! Length of the output vector |
| 168 | | Attribute::MappedAttributes attributes; |
| 169 | | |
| 170 | | public: |
| 171 | | //! Explanation for an user is the only obligatory attribute |
| 172 | | StringAttribute help; |
| 173 | | |
| 174 | | //! The only constructor which fills both the transcodedName and the help attribute |
| 175 | | UserInfo<T>( |
| 176 | | const string name, |
| 177 | | const string help_msg = "" ) |
| 178 | | : help("help"), |
| 179 | | transcodedName( XMLString::transcode( name.c_str() ) ) |
| | 114 | //! Mapped |
| | 115 | static MappedName2UI& mappedName2UI() |
| | 116 | { |
| | 117 | static MappedName2UI var; |
| | 118 | return var; |
| | 119 | } |
| | 120 | |
| | 121 | const string underlyingTypeName; |
| | 122 | |
| | 123 | public: |
| | 124 | |
| | 125 | //! The only constructor which fills both the transcodedTypeName and the help attribute |
| | 126 | UserInfo( const string& underlyingTypeName ) |
| | 127 | : underlyingTypeName ( underlyingTypeName ) |
| 181 | | XMLString::upperCase( transcodedName ); |
| 182 | | help.Attach( attributes ); |
| 183 | | help.value = help_msg; |
| 184 | | }; |
| 185 | | //! Destructor |
| 186 | | ~UserInfo<T>() |
| 187 | | { |
| 188 | | XMLString::release( (XMLCh**)&transcodedName ); |
| 189 | | } |
| 190 | | |
| 191 | | //! returns object of templated type filled with data stored in this UserInfo instance |
| 192 | | virtual T* build(void) = 0; |
| 193 | | |
| 194 | | //! Save UserInfo to the file (typically with an XML extension) |
| 195 | | void Save ( char* fileName ) |
| 196 | | { |
| 197 | | XMLCh* transcodedFileName = XMLString::transcode( fileName ); |
| 198 | | LocalFileFormatTarget outputTarget( transcodedFileName ); |
| 199 | | XMLString::release( &transcodedFileName ); |
| 200 | | |
| 201 | | DOMDocument* pDoc = XMLConnector.pImplementation->createDocument( |
| 202 | | XMLString::transcode( "M3K USER INFO" ), |
| 203 | | XMLString::transcode( "ROOT" ), NULL ); |
| 204 | | DOMElement *pRoot = pDoc->getDocumentElement(); |
| 205 | | |
| 206 | | FillElement( *pRoot ); |
| 207 | | |
| 208 | | XMLConnector.pSerializer->writeNode( &outputTarget, *pDoc); |
| 209 | | delete pDoc; |
| 210 | | } |
| 211 | | //! Load UserInfo from the file (typically with an XML extension) |
| 212 | | void Load ( char* fileName ) |
| 213 | | { |
| 214 | | bool bFailed = false; |
| 215 | | |
| 216 | | try |
| 217 | | { |
| 218 | | XMLCh* transcodedFileName = XMLString::transcode( fileName ) ; |
| 219 | | const LocalFileInputSource inputSource( transcodedFileName ); |
| 220 | | XMLString::release( &transcodedFileName ); |
| 221 | | |
| 222 | | XMLConnector.pParser->parse( inputSource ); |
| 223 | | bFailed = ( XMLConnector.pParser->getErrorCount() != 0 ); |
| 224 | | } |
| 225 | | catch (...) |
| 226 | | { |
| 227 | | bFailed = true; |
| 228 | | } |
| 229 | | |
| 230 | | if( !bFailed) |
| 231 | | { |
| 232 | | DOMDocument *pDoc = XMLConnector.pParser->getDocument(); |
| 233 | | DOMElement *pRoot = pDoc->getDocumentElement(); |
| 234 | | bFailed = true; |
| 235 | | for( DOMNode* node = pRoot->getFirstChild(); node != NULL; node = node->getNextSibling() ) |
| 236 | | if( node->getNodeType() == DOMNode::ELEMENT_NODE ) |
| 237 | | { |
| 238 | | ParseElement( (DOMElement*) node ); |
| 239 | | bFailed = false; |
| 240 | | break; |
| 241 | | } |
| 242 | | } |
| 243 | | |
| 244 | | if( bFailed ) |
| 245 | | { |
| 246 | | // exception?! |
| 247 | | } |
| 248 | | } |
| 249 | | //! This method is the key method to connect the element to its parent UI element |
| 250 | | void Attach( MappedElements &externalElements) |
| 251 | | { |
| 252 | | pair<const XMLCh* const, UserInfoCore* const> newPair( transcodedName, this ); |
| 253 | | externalElements.insert(newPair); |
| 254 | | } |
| | 129 | // trik, chci jen to, aby se inicializoval!! |
| | 130 | XercesConnector::instance(); |
| | 131 | |
| | 132 | cout << underlyingTypeName; |
| | 133 | |
| | 134 | mappedName2UI().insert( make_pair( underlyingTypeName, this ) ); |
| | 135 | } |
| | 136 | |
| | 137 | ~UserInfo() |
| | 138 | { |
| | 139 | } |
| | 140 | |
| | 141 | public: |
| 256 | | void ParseElement(DOMElement *element) |
| 257 | | { |
| 258 | | DOMNodeList* nodeList = element->getChildNodes(); |
| 259 | | if( nodeList ) |
| 260 | | for( int i = 0; i < nodeList->getLength(); i++ ) |
| | 143 | virtual void BuildInternal(void* &pInstance) = 0; |
| | 144 | |
| | 145 | //! returns object of templated type filled with data stored in this CompoundUserInfo instance |
| | 146 | // NULL if error.. |
| | 147 | template<class T> |
| | 148 | static void Assembly( const string tagName, DOMElement &element, T* &pInstance ) |
| | 149 | { |
| | 150 | pInstance = NULL; |
| | 151 | |
| | 152 | XMLCh* transcodedTagName = XMLString::transcode( tagName.c_str() ); |
| | 153 | XMLString::upperCase( transcodedTagName ); |
| | 154 | |
| | 155 | /*///////////////////////// |
| | 156 | DOMNodeList* nodeListe = element.getChildNodes(); |
| | 157 | if( nodeListe ) |
| | 158 | for( int i = 0; i < nodeListe->getLength(); i++ ) |
| 272 | | |
| 273 | | DOMNamedNodeMap* nodeMap = element->getAttributes(); |
| 274 | | if( nodeMap ) |
| 275 | | for( int i = 0; i < nodeMap->getLength(); i++ ) |
| | 167 | getchar(); |
| | 168 | |
| | 169 | *///////////////////////////// |
| | 170 | |
| | 171 | |
| | 172 | DOMNodeList* const nodeList = element.getElementsByTagName( transcodedTagName ); |
| | 173 | XMLString::release( (XMLCh**)&transcodedTagName ); |
| | 174 | |
| | 175 | if( nodeList != NULL && nodeList->getLength() != 1 ) |
| | 176 | return; |
| | 177 | |
| | 178 | // TAKZE MAME V RUCE ELEMENT SE JMENEM "tagName" |
| | 179 | DOMElement* childElement = (DOMElement*) nodeList->item(0); |
| | 180 | |
| | 181 | // COZ O TO, UDELAL BYCH TO STATICKOU KONSTANTOU, ALE JAK JI PAK SMAZU?? |
| | 182 | XMLCh* transcodedTypeAttributeName = XMLString::transcode("type"); |
| | 183 | const XMLCh* const transcodedType = childElement->getAttribute( transcodedTypeAttributeName ); |
| | 184 | XMLString::release( (XMLCh**)&transcodedTypeAttributeName ); |
| | 185 | |
| | 186 | if( !XMLString::stringLen( transcodedType ) ) |
| | 187 | return; |
| | 188 | |
| | 189 | // TED MAME V RUCE JMENO TYPU Z ATRIBUTU TYPE |
| | 190 | string type = XercesConnector::instance().XMLCh2str( transcodedType ); |
| | 191 | |
| | 192 | MappedName2UI::const_iterator iter = mappedName2UI().find( type ); |
| | 193 | if( iter == mappedName2UI().end()) |
| | 194 | return; |
| | 195 | |
| | 196 | // A TED PRISLUSNE UI |
| | 197 | UserInfo *relatedUI = iter->second; |
| | 198 | relatedUI->AssemblyBindedData( *childElement ); |
| | 199 | relatedUI->BuildInternal( (void*&)pInstance ); |
| | 200 | relatedUI->ReleaseUsedMemory(); |
| | 201 | |
| | 202 | if( pInstance == NULL ) |
| | 203 | return; |
| | 204 | |
| | 205 | try |
| | 206 | { |
| | 207 | // takhle to zkontroluju? name musi byt shodne s name nahore!! |
| | 208 | // takze mame typ T, ale name bud od jeho potomka.. oki?? |
| | 209 | string resultingType = typeid( *pInstance ).name(); |
| | 210 | if( resultingType != type ) |
| 277 | | DOMNode* node = nodeMap->item(i); |
| 278 | | if( node->getNodeType() == DOMNode::ATTRIBUTE_NODE ) |
| | 212 | cout << "FATAL ERROR!!" << endl; |
| | 213 | pInstance = NULL; |
| | 214 | } |
| | 215 | } |
| | 216 | catch(...) |
| | 217 | { |
| | 218 | // delete? ale jak na to? asi tezko |
| | 219 | pInstance = NULL; |
| | 220 | } |
| | 221 | return; |
| | 222 | } |
| | 223 | |
| | 224 | // ? pri destrukci si za ne naopak zodpovida ten, kdo je vytvoril.. protoze |
| | 225 | // budou zit v tom objektu!! tak jakapak destrkuce.. |
| | 226 | }; |
| | 227 | |
| | 228 | |
| | 229 | template<typename T> class TypedUserInfo : public UserInfo |
| | 230 | { |
| | 231 | protected: |
| | 232 | |
| | 233 | //! The only constructor which fills |
| | 234 | TypedUserInfo<T>( ) |
| | 235 | : UserInfo( typeid(T).name() ) |
| | 236 | { |
| | 237 | }; |
| | 238 | |
| | 239 | //! Destructor |
| | 240 | ~TypedUserInfo<T>() |
| | 241 | { |
| | 242 | } |
| | 243 | |
| | 244 | public: |
| | 245 | // FRIEND radeji |
| | 246 | void BuildInternal(void* &pInstance) |
| | 247 | { |
| | 248 | T* &pTypedInstance = (T*&) pInstance; |
| | 249 | Build( pTypedInstance ); |
| | 250 | } |
| | 251 | |
| | 252 | virtual void Build(T* &pTypedInstance) = 0; |
| | 253 | |
| | 254 | static const TypedUserInfo<T> &instance; |
| | 255 | }; |
| | 256 | |
| | 257 | |
| | 258 | |
| | 259 | /*! |
| | 260 | @brief The main user info template class |
| | 261 | |
| | 262 | You should derive this class whenever you need new CompoundUserInfo. |
| | 263 | */ |
| | 264 | template<typename T> class CompoundUserInfo : public TypedUserInfo<T> |
| | 265 | { |
| | 266 | private: |
| | 267 | //! Mapped elements, i.e., descendant html tags |
| | 268 | vector<BindingFrame* const> bindedElements; |
| | 269 | |
| | 270 | protected: |
| | 271 | template<typename U> class BindedType: public BindingFrame |
| | 272 | { |
| | 273 | private: |
| | 274 | const TypedUserInfo<U> &factory; |
| | 275 | string name; |
| | 276 | string help; |
| | 277 | |
| | 278 | public: |
| | 279 | U* pInstance; |
| | 280 | |
| | 281 | BindedType<U>( CompoundUserInfo<T> *parent, string name, string help ) |
| | 282 | : name( name), help(help) |
| | 283 | factory( TypedUserInfo<U>::instance ) |
| | 284 | { |
| | 285 | parent->bindedElements.push_back( this ); |
| | 286 | pInstance = NULL; |
| | 287 | } |
| | 288 | |
| | 289 | BindedType<U>( CompoundUserInfo<T> *parent, string name ) |
| | 290 | : name( name), help(""), |
| | 291 | factory( TypedUserInfo<U>::instance ) |
| | 292 | { |
| | 293 | parent->bindedElements.push_back( this ); |
| | 294 | pInstance = NULL; |
| | 295 | } |
| | 296 | |
| | 297 | void AssemblyBindedData( DOMElement &element ) |
| | 298 | { |
| | 299 | factory.Assembly( pInstance, element, name ); |
| | 300 | } |
| | 301 | |
| | 302 | void ReleaseUsedMemory() |
| | 303 | { |
| | 304 | if( pInstance != NULL ) |
| | 305 | delete pInstance; |
| | 306 | } |
| | 307 | |
| | 308 | bool DisassemblyBindedData( DOMElement &element ) |
| | 309 | { |
| | 310 | // return factory.Disassembly( (void*&) pInstance, element, name, help ); |
| | 311 | return true; |
| | 312 | } |
| | 313 | }; |
| | 314 | |
| | 315 | |
| | 316 | public: |
| | 317 | |
| | 318 | void AssemblyBindedData( DOMElement &element ) |
| | 319 | { |
| | 320 | for( unsigned int ind = 0; ind < bindedElements.size(); ind++ ) |
| | 321 | bindedElements[ind]->AssemblyBindedData( element ); |
| | 322 | } |
| | 323 | |
| | 324 | void ReleaseUsedMemory() |
| | 325 | { |
| | 326 | for( unsigned int ind = 0; ind < bindedElements.size(); ind++ ) |
| | 327 | bindedElements[ind]->ReleaseUsedMemory(); |
| | 328 | } |
| | 329 | |
| | 330 | bool DisassemblyBindedData( DOMElement &element ) |
| | 331 | { |
| | 332 | for( unsigned int ind = 0; ind < bindedElements.size(); ind++ ) |
| | 333 | if( !bindedElements[ind]->DisassemblyBindedData( element ) ) |
| | 334 | return false; |
| | 335 | return true; |
| | 336 | } |
| | 337 | }; |
| | 338 | |
| | 339 | |
| | 340 | /* |
| | 341 | //! returns object of templated type filled with data stored in this CompoundUserInfo instance |
| | 342 | bool Disassembly(void * &pInstance, DOMElement &element, string name, char * help = "" ) |
| | 343 | { |
| | 344 | T* &pTypedInstance = (T*&) pInstance; |
| | 345 | // do elementu prida vetev se jmenem name a vyplni obsahujici data z instance |
| | 346 | // zde nemuze vzniknout zadna chyba, ponevadz XML vytvarime |
| | 347 | |
| | 348 | /* |
| | 349 | for( MappedElements::const_iterator iter = elements.begin(); iter != elements.end(); iter++) |
| | 350 | { |
| | 351 | iter->second->AppendElement( *pHead ); |
| 290 | | } |
| 291 | | |
| 292 | | void FillElement(DOMElement &element) |
| 293 | | { |
| 294 | | DOMDocument* pDoc = element.getOwnerDocument(); |
| 295 | | |
| 296 | | DOMElement* pHead = pDoc->createElement( transcodedName ); |
| 297 | | element.appendChild( pHead ); |
| 298 | | |
| 299 | | for( MappedElements::const_iterator iter = elements.begin(); iter != elements.end(); iter++) |
| 300 | | iter->second->FillElement( *pHead ); |
| 301 | | |
| 302 | | for( Attribute::MappedAttributes::iterator iter = attributes.begin(); iter != attributes.end(); iter++) |
| 303 | | iter->second->FillAttribute( *pHead ); |
| 304 | | } |
| 305 | | }; |
| | 361 | |
| | 362 | for( MappedAttributes::iterator iter = attributes.begin(); iter != attributes.end(); iter++) |
| | 363 | { |
| | 364 | // we do not create attributes, which are empty |
| | 365 | if( !strcmp( iter->second->c_str(), "") ) |
| | 366 | continue; |
| | 367 | |
| | 368 | DOMDocument* pDoc = pHead->getOwnerDocument(); |
| | 369 | DOMAttr* pAttribute = pDoc->createAttribute( iter->first ); |
| | 370 | |
| | 371 | XMLCh* transcodedValue = XMLString::transcode( iter->second->c_str() ); |
| | 372 | pAttribute->setValue( transcodedValue ); |
| | 373 | XMLString::release( &transcodedValue ); |
| | 374 | |
| | 375 | pHead->setAttributeNode(pAttribute); |
| | 376 | } |
| | 377 | return true; |
| | 378 | } |
| | 379 | */ |
| | 380 | |
| | 381 | |
| | 382 | template<typename T> class ValuedUserInfo : public TypedUserInfo<T> |
| | 383 | { |
| | 384 | |
| | 385 | private: |
| | 386 | const XMLCh* const transcodedValueName; |
| | 387 | |
| | 388 | public: |
| | 389 | // Value nemusi byt pointer, na rozdil od ostatnich binding framu.. |
| | 390 | string value; |
| | 391 | |
| | 392 | ValuedUserInfo<T>() |
| | 393 | : transcodedValueName( XMLString::transcode( "value" )) |
| | 394 | { |
| | 395 | } |
| | 396 | |
| | 397 | ~ValuedUserInfo<T>() |
| | 398 | { |
| | 399 | XMLString::release( (XMLCh**)&transcodedValueName ); |
| | 400 | } |
| | 401 | |
| | 402 | void AssemblyBindedData( DOMElement &element ) |
| | 403 | { |
| | 404 | const XMLCh* const transcodedValue = element.getAttribute( transcodedValueName ); |
| | 405 | value = XercesConnector::instance().XMLCh2str( transcodedValue ); |
| | 406 | } |
| | 407 | |
| | 408 | void ReleaseUsedMemory() |
| | 409 | { |
| | 410 | } |
| | 411 | |
| | 412 | bool DisassemblyBindedData( DOMElement &element ) |
| | 413 | { |
| | 414 | // if( value.length()==0 ) |
| | 415 | // return false; |
| | 416 | return true; |
| | 417 | } |
| | 418 | }; |
| | 419 | |
| | 420 | |
| | 421 | class RootElement |
| | 422 | { |
| | 423 | // umi se pretypovat na DOMElement &element |
| | 424 | // a to vzdy, save a load se muze udelat az pak!! |
| | 425 | |
| | 426 | private: |
| | 427 | DOMElement * pRoot; |
| | 428 | DOMDocument* pDoc; |
| | 429 | |
| | 430 | const XMLCh* const transcodedFileName ; |
| | 431 | |
| | 432 | public: |
| | 433 | |
| | 434 | RootElement( char* fileName ) |
| | 435 | : transcodedFileName( XMLString::transcode( fileName ) ) |
| | 436 | { |
| | 437 | pDoc = XercesConnector::instance().pImplementation->createDocument( |
| | 438 | XMLString::transcode( "M3K USER INFO" ), |
| | 439 | XMLString::transcode( "ROOT" ), NULL ); |
| | 440 | pRoot = pDoc->getDocumentElement(); |
| | 441 | } |
| | 442 | |
| | 443 | ~RootElement() |
| | 444 | { |
| | 445 | XMLString::release( (XMLCh**)&transcodedFileName ); |
| | 446 | if( pDoc ) |
| | 447 | delete pDoc; |
| | 448 | } |
| | 449 | |
| | 450 | //! loads root element from a file |
| | 451 | bool Load( void ) |
| | 452 | { |
| | 453 | const LocalFileInputSource inputSource( transcodedFileName ); |
| | 454 | DOMDocument * newDoc = XercesConnector::instance().Parse( inputSource ); |
| | 455 | if( newDoc == NULL ) |
| | 456 | return false; |
| | 457 | |
| | 458 | if( pDoc ) |
| | 459 | delete pDoc; |
| | 460 | |
| | 461 | pDoc = newDoc; |
| | 462 | pRoot = pDoc->getDocumentElement(); |
| | 463 | return true; |
| | 464 | } |
| | 465 | |
| | 466 | |
| | 467 | //! Save UserInfo to the file (typically with an XML extension) |
| | 468 | void Save ( void ) |
| | 469 | { |
| | 470 | LocalFileFormatTarget outputTarget( transcodedFileName ); |
| | 471 | XercesConnector::instance().pSerializer->writeNode( &outputTarget, *pDoc); |
| | 472 | } |
| | 473 | |
| | 474 | operator DOMElement&() |
| | 475 | { |
| | 476 | return *pRoot; |
| | 477 | } |
| | 478 | }; |
| | 479 | |