00001
00005
00006
00008
00009 #include "XMLite.h"
00010 #include <iostream>
00011 #include <sstream>
00012 #include <string>
00013
00014 #ifdef UNICODE
00015 #define OSTREAM std::wostringstream
00016 #else
00017 #define OSTREAM std::ostringstream
00018 #endif
00019
00020 #pragma warning (disable: 4996)
00021
00022 static const TCHAR chXMLTagOpen = '<';
00023 static const TCHAR chXMLTagClose = '>';
00024 static const TCHAR chXMLTagPre = '/';
00025 static const TCHAR chXMLEscape = '\\';
00026
00027 static const TCHAR szXMLPIOpen[] = _T("<?");
00028 static const TCHAR szXMLPIClose[] = _T("?>");
00029 static const TCHAR szXMLCommentOpen[] = _T("<!--");
00030 static const TCHAR szXMLCommentClose[] = _T("-->");
00031 static const TCHAR szXMLCDATAOpen[] = _T("<![CDATA[");
00032 static const TCHAR szXMLCDATAClose[] = _T("]]>");
00033
00034 static const XENTITY x_EntityTable[] = {
00035 { '&', _T("&"), 5 } ,
00036 { '\"', _T("""), 6 } ,
00037 { '\'', _T("'"), 6 } ,
00038 { '<', _T("<"), 4 } ,
00039 { '>', _T(">"), 4 }
00040 };
00041
00042 PARSEINFO piDefault;
00043 DISP_OPT optDefault;
00044 XENTITYS entityDefault((LPXENTITY)x_EntityTable, sizeof(x_EntityTable)/sizeof(x_EntityTable[0]) );
00045
00046 #define lengthof(x) (sizeof(x)/sizeof(TCHAR))
00047
00049
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 LPTSTR _tcschrs( LPCTSTR psz, LPCTSTR pszchs )
00063 {
00064 while( psz && *psz )
00065 {
00066 if( _tcschr( pszchs, *psz ) )
00067 return (LPTSTR)psz;
00068 psz++;
00069 }
00070 return NULL;
00071 }
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 LPTSTR _tcsskip( LPCTSTR psz )
00083 {
00084
00085 while( psz && isspace(*psz) ) psz++;
00086
00087 return (LPTSTR)psz;
00088 }
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 LPTSTR _tcsechr( LPCTSTR psz, int ch, int escape )
00100 {
00101 LPTSTR pch = (LPTSTR)psz;
00102
00103 while( pch && *pch )
00104 {
00105 if( escape != 0 && *pch == escape )
00106 pch++;
00107 else
00108 if( *pch == ch )
00109 return (LPTSTR)pch;
00110 pch++;
00111 }
00112 return pch;
00113 }
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 int _tcselen( int escape, LPTSTR srt, LPTSTR end = NULL )
00125 {
00126 int len = 0;
00127 LPTSTR pch = srt;
00128 if( end==NULL ) end = (LPTSTR)sizeof(long);
00129 LPTSTR prev_escape = NULL;
00130 while( pch && *pch && pch<end )
00131 {
00132 if( escape != 0 && *pch == escape && prev_escape == NULL )
00133 prev_escape = pch;
00134 else
00135 {
00136 prev_escape = NULL;
00137 len++;
00138 }
00139 pch++;
00140 }
00141 return len;
00142 }
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153 void _tcsecpy( std::tstring* pString, int escape, LPTSTR srt, LPTSTR end = NULL )
00154 {
00155 *pString = _T("");
00156 LPTSTR pch = srt;
00157 if( end==NULL ) end = (LPTSTR)sizeof(long);
00158 LPTSTR prev_escape = NULL;
00159 while( pch && *pch && pch<end )
00160 {
00161 if( escape != 0 && *pch == escape && prev_escape == NULL )
00162 prev_escape = pch;
00163 else
00164 {
00165 prev_escape = NULL;
00166 *pString += *pch;
00167 }
00168
00169 pch++;
00170 }
00171 }
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182 LPTSTR _tcsepbrk( LPCTSTR psz, LPCTSTR chset, int escape )
00183 {
00184 LPTSTR pch = (LPTSTR)psz;
00185 LPTSTR prev_escape = NULL;
00186 while( pch && *pch )
00187 {
00188 if( escape != 0 && *pch == escape && prev_escape == NULL )
00189 prev_escape = pch;
00190 else
00191 {
00192 prev_escape = NULL;
00193 if( _tcschr( chset, *pch ) )
00194 return (LPTSTR)pch;
00195 }
00196 pch++;
00197 }
00198 return pch;
00199 }
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 int _tcsenicmp( LPCTSTR psz, LPCTSTR str, std::tstring::size_type len, int escape )
00211 {
00212 LPTSTR pch = (LPTSTR)psz;
00213 LPTSTR prev_escape = NULL;
00214 LPTSTR des = (LPTSTR)str;
00215 int i = 0;
00216
00217 while( pch && *pch && i < len )
00218 {
00219 if( escape != 0 && *pch == escape && prev_escape == NULL )
00220 prev_escape = pch;
00221 else
00222 {
00223 prev_escape = NULL;
00224 if( tolower(*pch) != tolower(des[i]) )
00225 break;
00226 i++;
00227 }
00228 pch ++;
00229 }
00230
00231
00232 if( i == len )
00233 return 0;
00234 if( psz[i] > des[i] )
00235 return 1;
00236 return -1;
00237 }
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248 LPTSTR _tcsenistr( LPCTSTR psz, LPCTSTR str, std::tstring::size_type len, int escape )
00249 {
00250 LPTSTR pch = (LPTSTR)psz;
00251 LPTSTR prev_escape = NULL;
00252 LPTSTR des = (LPTSTR)str;
00253 int i = 0;
00254
00255 while( pch && *pch )
00256 {
00257 if( escape != 0 && *pch == escape && prev_escape == NULL )
00258 prev_escape = pch;
00259 else
00260 {
00261 prev_escape = NULL;
00262 if( _tcsenicmp( pch, str, len, escape ) == 0 )
00263 return (LPTSTR)pch;
00264 }
00265 pch++;
00266 }
00267 return pch;
00268 }
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 LPTSTR _tcseistr( LPCTSTR psz, LPCTSTR str, int escape )
00280 {
00281 std::tstring::size_type len = _tcslen( str );
00282 return _tcsenistr( psz, str, len, escape );
00283 }
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294 void _SetString( LPTSTR psz, LPTSTR end, std::tstring* ps, bool trim = FALSE, int escape = 0 )
00295 {
00296
00297 if( trim )
00298 {
00299 while( psz && psz < end && _istspace(*psz) ) psz++;
00300 while( (end-1) && psz < (end-1) && _istspace(*(end-1)) ) end--;
00301 }
00302 std::tstring::size_type len = (end - psz);
00303 if( len <= 0 ) return;
00304 if( escape )
00305 {
00306 len = _tcselen( escape, psz, end );
00307 _tcsecpy( ps, escape, psz, end );
00308 }
00309 else
00310 {
00311 ps->assign(psz, len);
00312 }
00313 }
00314
00315 _tagXMLNode::~_tagXMLNode()
00316 {
00317 Close();
00318 }
00319
00320 void _tagXMLNode::Close()
00321 {
00322 for( XNodes::size_type iChild = 0 ; iChild < childs.size(); iChild++)
00323 {
00324 LPXNode p = childs[iChild];
00325 if( p )
00326 {
00327 delete p; childs[iChild] = NULL;
00328 }
00329 }
00330 childs.clear();
00331
00332 for( XAttrs::size_type iAttr = 0 ; iAttr < attrs.size(); iAttr++)
00333 {
00334 LPXAttr p = attrs[iAttr];
00335 if( p )
00336 {
00337 delete p; attrs[iAttr] = NULL;
00338 }
00339 }
00340 attrs.clear();
00341 }
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355 LPTSTR _tagXMLNode::LoadAttributes( LPCTSTR pszAttrs , LPPARSEINFO pi )
00356 {
00357 LPTSTR xml = (LPTSTR)pszAttrs;
00358
00359 while( xml && *xml )
00360 {
00361 if( xml = _tcsskip( xml ) )
00362 {
00363
00364 if( *xml == chXMLTagClose || *xml == chXMLTagPre )
00365
00366 return xml;
00367
00368
00369 TCHAR* pEnd = _tcspbrk( xml, _T(" =") );
00370 if( pEnd == NULL )
00371 {
00372
00373 if( pi->erorr_occur == false )
00374 {
00375 pi->erorr_occur = true;
00376 pi->error_pointer = xml;
00377 pi->error_code = PIE_ATTR_NO_VALUE;
00378 TCHAR err[1024];
00379 _stprintf(err, _T("<%.768s> attribute has error "), name.c_str() );
00380 pi->error_string = err;
00381 }
00382 return NULL;
00383 }
00384
00385 LPXAttr attr = new XAttr;
00386 attr->parent = this;
00387
00388
00389 _SetString( xml, pEnd, &attr->name );
00390
00391
00392 attrs.push_back( attr );
00393 xml = pEnd;
00394
00395
00396 if( xml = _tcsskip( xml ) )
00397 {
00398
00399 if( *xml == '=' )
00400 {
00401 if( xml = _tcsskip( ++xml ) )
00402 {
00403
00404
00405 int quote = *xml;
00406 if( quote == '"' || quote == '\'' )
00407 pEnd = _tcsechr( ++xml, quote, chXMLEscape );
00408 else
00409 {
00410
00411
00412
00413 pEnd = _tcsepbrk( xml, _T(" >"), chXMLEscape );
00414 }
00415
00416 bool trim = pi->trim_value;
00417 TCHAR escape = pi->escape_value;
00418
00419 _SetString( xml, pEnd, &attr->value, trim, escape );
00420 xml = pEnd;
00421
00422 if( pi->entity_value && pi->entitys )
00423 attr->value = pi->entitys->Ref2Entity(attr->value.c_str());
00424
00425 if( quote == '"' || quote == '\'' )
00426 xml++;
00427 }
00428 }
00429 }
00430 }
00431 }
00432
00433
00434 return NULL;
00435 }
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450 LPTSTR _tagXMLNode::LoadAttributes( LPCTSTR pszAttrs, LPCTSTR pszEnd, LPPARSEINFO pi )
00451 {
00452 LPTSTR xml = (LPTSTR)pszAttrs;
00453
00454 while( xml && *xml )
00455 {
00456 if( xml = _tcsskip( xml ) )
00457 {
00458
00459 if( xml >= pszEnd )
00460
00461 return xml;
00462
00463
00464 TCHAR* pEnd = _tcspbrk( xml, _T(" =") );
00465 if( pEnd == NULL )
00466 {
00467
00468 if( pi->erorr_occur == false )
00469 {
00470 pi->erorr_occur = true;
00471 pi->error_pointer = xml;
00472 pi->error_code = PIE_ATTR_NO_VALUE;
00473 TCHAR err[1024];
00474 _stprintf(err, _T("<%.768s> attribute has error "), name.c_str() );
00475 pi->error_string = err;
00476 }
00477 return NULL;
00478 }
00479
00480 LPXAttr attr = new XAttr;
00481 attr->parent = this;
00482
00483
00484 _SetString( xml, pEnd, &attr->name );
00485
00486
00487 attrs.push_back( attr );
00488 xml = pEnd;
00489
00490
00491 if( xml = _tcsskip( xml ) )
00492 {
00493
00494 if( *xml == '=' )
00495 {
00496 if( xml = _tcsskip( ++xml ) )
00497 {
00498
00499
00500 int quote = *xml;
00501 if( quote == '"' || quote == '\'' )
00502 pEnd = _tcsechr( ++xml, quote, chXMLEscape );
00503 else
00504 {
00505
00506
00507
00508 pEnd = _tcsepbrk( xml, _T(" >"), chXMLEscape );
00509 }
00510
00511 bool trim = pi->trim_value;
00512 TCHAR escape = pi->escape_value;
00513
00514 _SetString( xml, pEnd, &attr->value, trim, escape );
00515 xml = pEnd;
00516
00517 if( pi->entity_value && pi->entitys )
00518 attr->value = pi->entitys->Ref2Entity(attr->value.c_str());
00519
00520 if( quote == '"' || quote == '\'' )
00521 xml++;
00522 }
00523 }
00524 }
00525 }
00526 }
00527
00528
00529 return NULL;
00530 }
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544 LPTSTR _tagXMLNode::LoadProcessingInstrunction( LPCTSTR pszXml, LPPARSEINFO pi )
00545 {
00546
00547 LPTSTR end = _tcsenistr( pszXml, szXMLPIClose, lengthof(szXMLPIClose)-1, pi ? pi->escape_value : 0 );
00548 if( end == NULL )
00549 return NULL;
00550
00551
00552 if( doc )
00553 {
00554 LPTSTR xml = (LPTSTR)pszXml;
00555
00556 LPXNode node = new XNode;
00557 node->parent = this;
00558 node->doc = doc;
00559 node->type = XNODE_PI;
00560
00561 xml += lengthof(szXMLPIOpen)-1;
00562 TCHAR* pTagEnd = _tcspbrk( xml, _T(" ?>") );
00563 _SetString( xml, pTagEnd, &node->name );
00564 xml = pTagEnd;
00565
00566 node->LoadAttributes( xml, end, pi );
00567
00568 doc->childs.push_back( node );
00569 }
00570
00571 end += lengthof(szXMLPIClose)-1;
00572 return end;
00573 }
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587 LPTSTR _tagXMLNode::LoadComment( LPCTSTR pszXml, LPPARSEINFO pi )
00588 {
00589
00590 LPTSTR end = _tcsenistr( pszXml, szXMLCommentClose, lengthof(szXMLCommentClose)-1, pi ? pi->escape_value : 0 );
00591 if( end == NULL )
00592 return NULL;
00593
00594
00595 LPXNode par = parent;
00596 if( parent == NULL && doc )
00597 par = (LPXNode)&doc;
00598 if( par )
00599 {
00600 LPTSTR xml = (LPTSTR)pszXml;
00601 xml += lengthof(szXMLCommentOpen)-1;
00602
00603 LPXNode node = new XNode;
00604 node->parent = this;
00605 node->doc = doc;
00606 node->type = XNODE_COMMENT;
00607 node->name = _T("#COMMENT");
00608 _SetString( xml, end, &node->value, FALSE );
00609
00610 par->childs.push_back( node );
00611 }
00612
00613 end += lengthof(szXMLCommentClose)-1;
00614 return end;
00615 }
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629 LPTSTR _tagXMLNode::LoadCDATA( LPCTSTR pszXml, LPPARSEINFO pi )
00630 {
00631
00632 LPTSTR end = _tcsenistr( pszXml, szXMLCDATAClose, lengthof(szXMLCDATAClose)-1, pi ? pi->escape_value : 0 );
00633 if( end == NULL )
00634 return NULL;
00635
00636
00637 LPXNode par = parent;
00638 if( parent == NULL && doc )
00639 par = (LPXNode)&doc;
00640 if( par )
00641 {
00642 LPTSTR xml = (LPTSTR)pszXml;
00643 xml += lengthof(szXMLCDATAOpen)-1;
00644
00645 LPXNode node = new XNode;
00646 node->parent = this;
00647 node->doc = doc;
00648 node->type = XNODE_CDATA;
00649 node->name = _T("#CDATA");
00650 _SetString( xml, end, &node->value, FALSE );
00651
00652 par->childs.push_back( node );
00653 }
00654
00655 end += lengthof(szXMLCDATAClose)-1;
00656 return end;
00657 }
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671 LPTSTR LoadOtherNodes( LPXNode node, bool* pbRet, LPCTSTR pszXml, LPPARSEINFO pi )
00672 {
00673 LPTSTR xml = (LPTSTR)pszXml;
00674 bool do_other_type = true;
00675 *pbRet = false;
00676
00677 while( xml && do_other_type )
00678 {
00679 do_other_type = false;
00680
00681 xml = _tcsskip( xml );
00682 LPTSTR prev = xml;
00683
00684 if( _tcsnicmp( xml, szXMLPIOpen, lengthof(szXMLPIOpen)-1 ) == 0 )
00685 {
00686
00687
00688 xml = node->LoadProcessingInstrunction( xml, pi );
00689
00690
00691
00692 }
00693
00694 if( xml != prev )
00695 do_other_type = true;
00696 xml = _tcsskip( xml );
00697 prev = xml;
00698
00699
00700 if( _tcsnicmp( xml, szXMLCommentOpen, lengthof(szXMLCommentOpen)-1 ) == 0 )
00701 {
00702
00703
00704 xml = node->LoadComment( xml, pi );
00705
00706 if( node->parent && node->parent->type != XNODE_DOC
00707 && xml != prev )
00708 {
00709 *pbRet = true;
00710 return xml;
00711 }
00712
00713 }
00714
00715 if( xml != prev )
00716 do_other_type = true;
00717
00718 xml = _tcsskip( xml );
00719 prev = xml;
00720
00721 if( _tcsnicmp( xml, szXMLCDATAOpen, lengthof(szXMLCDATAOpen)-1 ) == 0 )
00722 {
00723
00724
00725 xml = node->LoadCDATA( xml, pi );
00726
00727 if( node->parent && node->parent->type != XNODE_DOC
00728 && xml != prev )
00729 {
00730 *pbRet = true;
00731 return xml;
00732 }
00733
00734 }
00735
00736 if( xml != prev )
00737 do_other_type = true;
00738 }
00739
00740 return xml;
00741 }
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758 LPTSTR _tagXMLNode::Load( LPCTSTR pszXml, LPPARSEINFO pi )
00759 {
00760
00761 Close();
00762
00763 LPTSTR xml = (LPTSTR)pszXml;
00764
00765 xml = _tcschr( xml, chXMLTagOpen );
00766 if( xml == NULL )
00767 return NULL;
00768
00769
00770 if( *(xml+1) == chXMLTagPre )
00771 return xml;
00772
00773
00774 bool bRet = false;
00775 LPTSTR ret = NULL;
00776 ret = LoadOtherNodes( this, &bRet, xml, pi );
00777 if( ret != NULL )
00778 xml = ret;
00779 if( bRet )
00780 return xml;
00781
00782
00783 xml++;
00784 TCHAR* pTagEnd = _tcspbrk( xml, _T(" />\t\r\n") );
00785 _SetString( xml, pTagEnd, &name );
00786 xml = pTagEnd;
00787
00788 if( xml = LoadAttributes( xml, pi ) )
00789 {
00790
00791 if( *xml == chXMLTagPre )
00792 {
00793 xml++;
00794 if( *xml == chXMLTagClose )
00795
00796 return ++xml;
00797 else
00798 {
00799
00800 if( pi->erorr_occur == false )
00801 {
00802 pi->erorr_occur = true;
00803 pi->error_pointer = xml;
00804 pi->error_code = PIE_ALONE_NOT_CLOSED;
00805 pi->error_string = _T("Element must be closed.");
00806 }
00807
00808 return NULL;
00809 }
00810 }
00811 else
00812
00813
00814 {
00815
00816
00817 if( XIsEmptyString( value ) )
00818 {
00819
00820 TCHAR* pEnd = _tcsechr( ++xml, chXMLTagOpen, chXMLEscape );
00821 if( pEnd == NULL )
00822 {
00823 if( pi->erorr_occur == false )
00824 {
00825 pi->erorr_occur = true;
00826 pi->error_pointer = xml;
00827 pi->error_code = PIE_NOT_CLOSED;
00828 TCHAR err[1024];
00829 _stprintf(err, _T("%.256s must be closed with </%.256s>"), name.c_str(), name.c_str() );
00830 pi->error_string = err;
00831 }
00832
00833 return NULL;
00834 }
00835
00836 bool trim = pi->trim_value;
00837 TCHAR escape = pi->escape_value;
00838
00839 _SetString( xml, pEnd, &value, trim, escape );
00840
00841 xml = pEnd;
00842
00843 if( pi->entity_value && pi->entitys )
00844 value = pi->entitys->Ref2Entity(value.c_str());
00845 }
00846
00847
00848 while( xml && *xml )
00849 {
00850 LPXNode node = new XNode;
00851 node->parent = this;
00852 node->doc = doc;
00853 node->type = type;
00854
00855 xml = node->Load( xml,pi );
00856 if(!node->name.empty())
00857 {
00858 childs.push_back( node );
00859 }
00860 else
00861 {
00862 delete node;
00863 }
00864
00865
00866
00867
00868 if( xml && *xml && *(xml+1) && *xml == chXMLTagOpen && *(xml+1) == chXMLTagPre )
00869 {
00870
00871 xml+=2;
00872
00873 if( xml = _tcsskip( xml ) )
00874 {
00875 std::tstring closename;
00876 TCHAR* pEnd = _tcspbrk( xml, _T(" >") );
00877 if( pEnd == NULL )
00878 {
00879 if( pi->erorr_occur == false )
00880 {
00881 pi->erorr_occur = true;
00882 pi->error_pointer = xml;
00883 pi->error_code = PIE_NOT_CLOSED;
00884 TCHAR err[1024];
00885 _stprintf(err, _T("it must be closed with </%.768s>"), name.c_str() );
00886 pi->error_string = err;
00887 }
00888
00889 return NULL;
00890 }
00891 _SetString( xml, pEnd, &closename );
00892 if( closename == this->name )
00893 {
00894
00895 xml = pEnd+1;
00896
00897 return xml;
00898 }
00899 else
00900 {
00901 xml = pEnd+1;
00902
00903
00904 if( pi->force_parse == false )
00905 {
00906
00907 if( pi->erorr_occur == false )
00908 {
00909 pi->erorr_occur = true;
00910 pi->error_pointer = xml;
00911 pi->error_code = PIE_NOT_NESTED;
00912 TCHAR err[1024];
00913 _stprintf(err, _T("'<%.256s> ... </%.256s>' is not wel-formed."), name.c_str(), closename.c_str());
00914 pi->error_string = err;
00915 }
00916 return NULL;
00917 }
00918 }
00919 }
00920 }
00921 else
00922
00923 {
00924
00925
00926 if( xml && XIsEmptyString( value ) && *xml !=chXMLTagOpen )
00927 {
00928
00929 TCHAR* pEnd = _tcsechr( xml, chXMLTagOpen, chXMLEscape );
00930 if( pEnd == NULL )
00931 {
00932
00933 if( pi->erorr_occur == false )
00934 {
00935 pi->erorr_occur = true;
00936 pi->error_pointer = xml;
00937 pi->error_code = PIE_NOT_CLOSED;
00938 TCHAR err[1024];
00939 _stprintf(err, _T("it must be closed with </%.768s>"), name.c_str() );
00940 pi->error_string = err;
00941 }
00942 return NULL;
00943 }
00944
00945 bool trim = pi->trim_value;
00946 TCHAR escape = pi->escape_value;
00947
00948 _SetString( xml, pEnd, &value, trim, escape );
00949
00950 xml = pEnd;
00951
00952 if( pi->entity_value && pi->entitys )
00953 value = pi->entitys->Ref2Entity(value.c_str());
00954 }
00955 }
00956 }
00957 }
00958 }
00959
00960 return xml;
00961 }
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979 LPTSTR _tagXMLDocument::Load( LPCTSTR pszXml, LPPARSEINFO pi )
00980 {
00981 LPXNode node = new XNode;
00982 node->parent = (LPXNode)this;
00983 node->type = XNODE_ELEMENT;
00984 node->doc = this;
00985 LPTSTR end;
00986
00987 if( pi == NULL )
00988 pi = &parse_info;
00989
00990 if( (end = node->Load( pszXml, pi )) == NULL )
00991 {
00992 delete node;
00993 return NULL;
00994 }
00995
00996 childs.push_back( node );
00997
00998
00999 LPTSTR ret;
01000 bool bRet = false;
01001 ret = LoadOtherNodes( node, &bRet, end, pi );
01002 if( ret != NULL )
01003 end = ret;
01004
01005 return end;
01006 }
01007
01008 const XDoc& _tagXMLDocument::operator = ( const XDoc& doc )
01009 {
01010 Close();
01011 _CopyBranch( (const LPXNode)&doc, this );
01012 return *this;
01013 }
01014
01015
01016 LPXNode _tagXMLDocument::GetRoot()
01017 {
01018 XNodes::iterator it = childs.begin();
01019 for( ; it != childs.end() ; ++(it) )
01020 {
01021 LPXNode node = *it;
01022 if( node->type == XNODE_ELEMENT )
01023 return node;
01024 }
01025 return NULL;
01026 }
01027
01028 const LPXNode _tagXMLDocument::GetRoot() const
01029 {
01030 XNodes::const_iterator it = childs.begin();
01031 for( ; it != childs.end() ; ++(it) )
01032 {
01033 const LPXNode node = *it;
01034 if( node->type == XNODE_ELEMENT )
01035 return node;
01036 }
01037 return NULL;
01038 }
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049 std::tstring _tagXMLAttr::GetXML( LPDISP_OPT opt ) const
01050 {
01051 OSTREAM os;
01052
01053
01054 os << name.c_str() << _T("=") << (TCHAR)opt->value_quotation_mark
01055 << ((opt->reference_value&&opt->entitys) ? opt->entitys->Entity2Ref(value.c_str()).c_str() : value.c_str())
01056 << (TCHAR)opt->value_quotation_mark << _T(" ");
01057 return os.str();
01058 }
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069 std::tstring _tagXMLNode::GetXML( LPDISP_OPT opt ) const
01070 {
01071 OSTREAM os;
01072
01073
01074 if( opt && opt->newline )
01075 {
01076 if( opt && opt->newline )
01077 os << _T("\r\n");
01078 for( int i = 0 ; i < opt->tab_base ; i++)
01079 os << _T("\t");
01080 }
01081
01082 if( type == XNODE_DOC )
01083 {
01084 for( XNodes::size_type i = 0 ; i < childs.size(); i++ )
01085 os << childs[i]->GetXML( opt ).c_str();
01086 return os.str();
01087 }
01088 else
01089 if( type == XNODE_PI )
01090 {
01091
01092 os << szXMLPIOpen << name.c_str();
01093
01094 if( !attrs.empty() ) os << _T(" ");
01095 for( XAttrs::size_type i = 0 ; i < attrs.size(); i++ )
01096 {
01097 os << attrs[i]->GetXML(opt).c_str();
01098 }
01099
01100 os << szXMLPIClose;
01101 return os.str();
01102 }
01103 else
01104 if( type == XNODE_COMMENT )
01105 {
01106
01107 os << szXMLCommentOpen << value.c_str();
01108
01109 os << szXMLCommentClose;
01110 return os.str();
01111 }
01112 else
01113 if( type == XNODE_CDATA )
01114 {
01115
01116 os << szXMLCDATAOpen << value.c_str();
01117
01118 os << szXMLCDATAClose;
01119 return os.str();
01120 }
01121
01122
01123 os << _T("<") << name.c_str();
01124
01125
01126 if( attrs.empty() == false ) os << _T(" ");
01127 for( XAttrs::size_type i = 0 ; i < attrs.size(); i++ )
01128 {
01129 os << attrs[i]->GetXML(opt).c_str();
01130 }
01131
01132 if( childs.empty() && value.empty() )
01133 {
01134
01135 os << _T("/>");
01136 }
01137 else
01138 {
01139
01140 os << _T(">");
01141 if( opt && opt->newline && !childs.empty() )
01142 {
01143 opt->tab_base++;
01144 }
01145
01146 for( XNodes::size_type i = 0 ; i < childs.size(); i++ )
01147 os << childs[i]->GetXML( opt ).c_str();
01148
01149
01150 if( value != _T("") )
01151 {
01152 if( opt && opt->newline && !childs.empty() )
01153 {
01154 if( opt && opt->newline )
01155 os << _T("\r\n");
01156 for( int i = 0 ; i < opt->tab_base ; i++)
01157 os << _T("\t");
01158 }
01159 os << ((opt->reference_value&&opt->entitys) ? opt->entitys->Entity2Ref(value.c_str()).c_str() : value.c_str());
01160 }
01161
01162
01163 if( opt && opt->newline && !childs.empty() )
01164 {
01165 os << _T("\r\n");
01166 for( int i = 0 ; i < opt->tab_base-1 ; i++)
01167 os << _T("\t");
01168 }
01169 os << _T("</") << name.c_str() << _T(">");
01170
01171 if( opt && opt->newline )
01172 {
01173 if( !childs.empty() )
01174 opt->tab_base--;
01175 }
01176 }
01177
01178 return os.str();
01179 }
01180
01181 void AddNextTextChar(LPDISP_OPT opt, LPCTSTR lpChar, std::tstring& sTo)
01182 {
01183 if (opt->reference_value&&opt->entitys)
01184 opt->entitys->Entity2Ref(lpChar, sTo, 1);
01185 else
01186 sTo.append(lpChar, 1);
01187 }
01188
01189 std::tstring _tagXMLNode::GetTextFromValue(LPDISP_OPT opt) const
01190 {
01191 std::tstring sRet;
01192 std::tstring::size_type i, iStart;
01193 std::tstring::size_type nLen = (int)value.size();
01194 std::tstring s;
01195 WCHAR w[2];
01196 w[1] = '\0';
01197 LPCTSTR lpValue = value.c_str();
01198 for (i=0;i<nLen-2;i++)
01199 {
01200 if ((lpValue[i] == '&') && (lpValue[i+1] == '#'))
01201 {
01202
01203 bool bHex = false;
01204 iStart = i + 2;
01205 if (lpValue[iStart] == 'x')
01206 {
01207 iStart++;
01208 bHex = true;
01209 }
01210
01211 TCHAR* p;
01212 w[0] = (WCHAR)_tcstol(lpValue + iStart, &p, bHex ? 16 : 10);
01213 if (*p == ';')
01214 {
01215 s = MakeTString(w);
01216 AddNextTextChar(opt, s.c_str(), sRet);
01217 i = (p - lpValue) + 1;
01218 continue;
01219 }
01220 }
01221 AddNextTextChar(opt, lpValue + i, sRet);
01222 }
01223 for (; i < nLen;i++)
01224 AddNextTextChar(opt, lpValue + i, sRet);
01225
01226 return sRet;
01227 }
01228
01229 std::tstring _tagXMLNode::GetText( LPDISP_OPT opt ) const
01230 {
01231 OSTREAM os;
01232
01233 if( type == XNODE_DOC )
01234 {
01235 for( XNodes::size_type i = 0 ; i < childs.size(); i++ )
01236 os << childs[i]->GetText( opt ).c_str();
01237 }
01238 else
01239 if( type == XNODE_PI )
01240 {
01241
01242 }
01243 else
01244 if( type == XNODE_COMMENT )
01245 {
01246
01247 }
01248 else
01249 if( type == XNODE_CDATA )
01250 {
01251 os << value.c_str();
01252 }
01253 else
01254 if( type == XNODE_ELEMENT )
01255 {
01256 if( childs.empty() && value.empty() )
01257 {
01258
01259 }
01260 else
01261 {
01262
01263 for( XNodes::size_type i = 0 ; i < childs.size(); i++ )
01264 os << childs[i]->GetText(opt).c_str();
01265
01266
01267 os << GetTextFromValue(opt);
01268 }
01269 }
01270
01271 return os.str();
01272 }
01273
01274 std::tstring _tagXMLAttr::GetValue( LPDISP_OPT opt ) const
01275 {
01276 OSTREAM os;
01277
01278
01279 os << ((opt->reference_value&&opt->entitys) ? opt->entitys->Entity2Ref(value.c_str()) : value.c_str());
01280
01281 return os.str();
01282 }
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293 LPXAttr _tagXMLNode::GetAttr( LPCTSTR attrname )
01294 {
01295 for( XAttrs::size_type i = 0 ; i < attrs.size(); i++ )
01296 {
01297 LPXAttr attr = attrs[i];
01298 if( attr )
01299 {
01300 if( attr->name == attrname )
01301 return attr;
01302 }
01303 }
01304 return NULL;
01305 }
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316 XAttrs _tagXMLNode::GetAttrs( LPCTSTR name )
01317 {
01318 XAttrs attrs;
01319 for( XAttrs::size_type i = 0 ; i < attrs.size(); i++ )
01320 {
01321 LPXAttr attr = attrs[i];
01322 if( attr )
01323 {
01324 if( attr->name == name )
01325 attrs.push_back( attr );
01326 }
01327 }
01328 return attrs;
01329 }
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340 LPCTSTR _tagXMLNode::GetAttrValue( LPCTSTR attrname )
01341 {
01342 LPXAttr attr = GetAttr( attrname );
01343 return attr ? attr->value.c_str() : NULL;
01344 }
01345
01346 XNodes _tagXMLNode::GetChilds()
01347 {
01348 return childs;
01349 }
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360 XNodes _tagXMLNode::GetChilds( LPCTSTR name )
01361 {
01362 XNodes nodes;
01363 for( XNodes::size_type i = 0 ; i < childs.size(); i++ )
01364 {
01365 LPXNode node = childs[i];
01366 if( node )
01367 {
01368 if( node->name == name )
01369 nodes.push_back( node );
01370 }
01371 }
01372 return nodes;
01373 }
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384 LPXNode _tagXMLNode::GetChild( XNodes::size_type i )
01385 {
01386 if( i >= 0 && i < childs.size() )
01387 return childs[i];
01388 return NULL;
01389 }
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400 std::tstring::size_type _tagXMLNode::GetChildCount()
01401 {
01402 return childs.size();
01403 }
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414 LPXNode _tagXMLNode::GetChild( LPCTSTR name )
01415 {
01416 for( XNodes::size_type i = 0 ; i < childs.size(); i++ )
01417 {
01418 LPXNode node = childs[i];
01419 if( node )
01420 {
01421 if( node->name == name )
01422 return node;
01423 }
01424 }
01425 return NULL;
01426 }
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437 LPCTSTR _tagXMLNode::GetChildValue( LPCTSTR name )
01438 {
01439 LPXNode node = GetChild( name );
01440 return (node != NULL)? node->value.c_str() : NULL;
01441 }
01442
01443 std::tstring _tagXMLNode::GetChildText( LPCTSTR name, LPDISP_OPT opt )
01444 {
01445 LPXNode node = GetChild( name );
01446 return (node != NULL)? node->GetText(opt).c_str() : _T("");
01447 }
01448
01449 LPXAttr _tagXMLNode::GetChildAttr( LPCTSTR name, LPCTSTR attrname )
01450 {
01451 LPXNode node = GetChild(name);
01452 return node ? node->GetAttr(attrname) : NULL;
01453 }
01454
01455 LPCTSTR _tagXMLNode::GetChildAttrValue( LPCTSTR name, LPCTSTR attrname )
01456 {
01457 LPXAttr attr = GetChildAttr( name, attrname );
01458 return attr ? attr->value.c_str() : NULL;
01459 }
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470 LPXNode _tagXMLNode::Find( LPCTSTR name )
01471 {
01472 XNodes::iterator it = childs.begin();
01473 for( ; it != childs.end(); ++(it))
01474 {
01475 LPXNode child = *it;
01476 if( child->name == name )
01477 return child;
01478
01479 XNodes::iterator it = child->childs.begin();
01480 for( ; it != child->childs.end(); ++(it))
01481 {
01482 LPXNode find = child->Find( name );
01483 if( find != NULL )
01484 return find;
01485 }
01486 }
01487
01488 return NULL;
01489 }
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500 const LPXNode _tagXMLNode::Find( LPCTSTR name ) const
01501 {
01502 XNodes::const_iterator it = childs.begin();
01503 for( ; it != childs.end(); ++(it))
01504 {
01505 LPXNode child = *it;
01506 if( child->name == name )
01507 return child;
01508
01509 XNodes::const_iterator it = child->childs.begin();
01510 for( ; it != child->childs.end(); ++(it))
01511 {
01512 const LPXNode find = child->Find( name );
01513 if( find != NULL )
01514 return find;
01515 }
01516 }
01517
01518 return NULL;
01519 }
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530 LPXNode _tagXMLNode::Find( LPCTSTR name, LPCTSTR id )
01531 {
01532 XNodes::iterator it = childs.begin();
01533 for( ; it != childs.end(); ++(it))
01534 {
01535 LPXNode child = *it;
01536 if( child->name == name )
01537 {
01538 LPXAttr attr = child->GetAttr(_T("id"));
01539 if ((attr != NULL) && (attr->value == id))
01540 return child;
01541 }
01542
01543 XNodes::iterator it = child->childs.begin();
01544 for( ; it != child->childs.end(); ++(it))
01545 {
01546 LPXNode find = child->Find( name, id );
01547 if( find != NULL )
01548 return find;
01549 }
01550 }
01551
01552 return NULL;
01553 }
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564 const LPXNode _tagXMLNode::Find( LPCTSTR name, LPCTSTR id ) const
01565 {
01566 XNodes::const_iterator it = childs.begin();
01567 for( ; it != childs.end(); ++(it))
01568 {
01569 LPXNode child = *it;
01570 if( child->name == name )
01571 {
01572 const LPXAttr attr = child->GetAttr(_T("id"));
01573 if ((attr != NULL) && (attr->value == id))
01574 return child;
01575 }
01576
01577 XNodes::const_iterator it = child->childs.begin();
01578 for( ; it != child->childs.end(); ++(it))
01579 {
01580 const LPXNode find = child->Find( name, id );
01581 if( find != NULL )
01582 return find;
01583 }
01584 }
01585
01586 return NULL;
01587 }
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598 XNodes::iterator _tagXMLNode::GetChildIterator( LPXNode node )
01599 {
01600 XNodes::iterator it = childs.begin();
01601 for( ; it != childs.end() ; ++(it) )
01602 {
01603 if( *it == node )
01604 return it;
01605 }
01606 return childs.end();
01607 }
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618 LPXNode _tagXMLNode::AppendChild( LPCTSTR name , LPCTSTR value )
01619 {
01620 return AppendChild( CreateNode( name, value ) );
01621 }
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632 LPXNode _tagXMLNode::AppendChild( LPXNode node )
01633 {
01634 node->parent = this;
01635 node->doc = doc;
01636 childs.push_back( node );
01637 return node;
01638 }
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649 bool _tagXMLNode::RemoveChild( LPXNode node )
01650 {
01651 XNodes::iterator it = GetChildIterator( node );
01652 if( it != childs.end() )
01653 {
01654 delete *it;
01655 childs.erase( it );
01656 return true;
01657 }
01658 return false;
01659 }
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670 LPXAttr _tagXMLNode::GetAttr( XAttrs::size_type i )
01671 {
01672 if( i >= 0 && i < attrs.size() )
01673 return attrs[i];
01674 return NULL;
01675 }
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686 XAttrs::iterator _tagXMLNode::GetAttrIterator( LPXAttr attr )
01687 {
01688 XAttrs::iterator it = attrs.begin();
01689 for( ; it != attrs.end() ; ++(it) )
01690 {
01691 if( *it == attr )
01692 return it;
01693 }
01694 return attrs.end();
01695 }
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706 LPXAttr _tagXMLNode::AppendAttr( LPXAttr attr )
01707 {
01708 attr->parent = this;
01709 attrs.push_back( attr );
01710 return attr;
01711 }
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722 bool _tagXMLNode::RemoveAttr( LPXAttr attr )
01723 {
01724 XAttrs::iterator it = GetAttrIterator( attr );
01725 if( it != attrs.end() )
01726 {
01727 delete *it;
01728 attrs.erase( it );
01729 return true;
01730 }
01731 return false;
01732 }
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743 LPXNode _tagXMLNode::CreateNode( LPCTSTR name , LPCTSTR value )
01744 {
01745 LPXNode node = new XNode;
01746 node->name = name == NULL ? _T("") : name;
01747 node->value = value == NULL ? _T("") : value;
01748 return node;
01749 }
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760 LPXAttr _tagXMLNode::CreateAttr( LPCTSTR name , LPCTSTR value )
01761 {
01762 LPXAttr attr = new XAttr;
01763 attr->name = name == NULL ? _T("") : name;
01764 attr->value = value == NULL ? _T("") : value;
01765 return attr;
01766 }
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777 LPXAttr _tagXMLNode::AppendAttr( LPCTSTR name , LPCTSTR value )
01778 {
01779 return AppendAttr( CreateAttr( name, value ) );
01780 }
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791 LPXNode _tagXMLNode::DetachChild( LPXNode node )
01792 {
01793 XNodes::iterator it = GetChildIterator( node );
01794 if( it != childs.end() )
01795 {
01796 childs.erase( it );
01797 return node;
01798 }
01799 return NULL;
01800 }
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811 LPXAttr _tagXMLNode::DetachAttr( LPXAttr attr )
01812 {
01813 XAttrs::iterator it = GetAttrIterator( attr );
01814 if( it != attrs.end() )
01815 {
01816 attrs.erase( it );
01817 return attr;
01818 }
01819 return NULL;
01820 }
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831 void _tagXMLNode::CopyNode( LPXNode node )
01832 {
01833 Close();
01834
01835 doc = node->doc;
01836 parent = node->parent;
01837 name = node->name;
01838 value = node->value;
01839 type = node->type;
01840
01841
01842 for( XAttrs::size_type i = 0 ; i < node->attrs.size(); i++)
01843 {
01844 LPXAttr attr = node->attrs[i];
01845 if( attr )
01846 AppendAttr( attr->name.c_str(), attr->value.c_str() );
01847 }
01848 }
01849
01850
01851
01852
01853
01854
01855
01856
01857
01858
01859 void _tagXMLNode::_CopyBranch( const LPXNode node, LPXDoc docNew )
01860 {
01861 CopyNode( node );
01862 if (docNew != NULL)
01863 doc = docNew;
01864
01865 for( XNodes::size_type i = 0 ; i < node->childs.size(); i++)
01866 {
01867 LPXNode child = node->childs[i];
01868 if( child )
01869 {
01870 LPXNode mychild = new XNode;
01871 mychild->CopyNode( child );
01872 AppendChild( mychild );
01873
01874 mychild->_CopyBranch( child, docNew );
01875 }
01876 }
01877 }
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888 LPXNode _tagXMLNode::AppendChildBranch( LPXNode node )
01889 {
01890 LPXNode child = new XNode;
01891 child->CopyBranch( node );
01892
01893 return AppendChild( child );
01894 }
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905 void _tagXMLNode::CopyBranch( const LPXNode branch )
01906 {
01907 Close();
01908
01909 _CopyBranch( branch );
01910 }
01911
01912
01913 _tagXMLEntitys::_tagXMLEntitys( LPXENTITY entities, int count )
01914 {
01915 for( int i = 0; i < count; i++)
01916 push_back( entities[i] );
01917 }
01918
01919 LPXENTITY _tagXMLEntitys::GetEntity( int entity )
01920 {
01921 for( size_type i = 0 ; i < size(); i ++ )
01922 {
01923 if( at(i).entity == entity )
01924 return LPXENTITY(&at(i));
01925 }
01926 return NULL;
01927 }
01928
01929 LPXENTITY _tagXMLEntitys::GetEntity( LPCTSTR entity )
01930 {
01931 for( size_type i = 0 ; i < size(); i ++ )
01932 {
01933 LPCTSTR ref = (LPTSTR)at(i).ref;
01934 LPCTSTR ps = entity;
01935 while( ref && *ref )
01936 if( *ref++ != *ps++ )
01937 break;
01938 if( ref && !*ref )
01939 return LPXENTITY(&at(i));
01940 }
01941 return NULL;
01942 }
01943
01944 int _tagXMLEntitys::GetEntityCount( LPCTSTR str )
01945 {
01946 int nCount = 0;
01947 LPTSTR ps = (LPTSTR)str;
01948 while( ps && *ps )
01949 if( GetEntity( *ps++ ) ) nCount ++;
01950 return nCount;
01951 }
01952
01953 std::tstring::size_type _tagXMLEntitys::Ref2Entity( LPCTSTR estr, std::tstring& str, int elen )
01954 {
01955 std::tstring::size_type nBefore = str.size();
01956 LPCTSTR estr_end = estr+elen;
01957 while( estr && *estr && (estr < estr_end) )
01958 {
01959 LPXENTITY ent = GetEntity( estr );
01960 if( ent )
01961 {
01962
01963 str += ent->entity;
01964 estr += ent->ref_len;
01965 }
01966 else
01967 str += *estr++;
01968 }
01969
01970
01971 return (str.size() - nBefore);
01972 }
01973
01974 std::tstring::size_type _tagXMLEntitys::Ref2Entity( LPCTSTR estr, LPTSTR str, int len )
01975 {
01976 LPTSTR ps = str;
01977 LPTSTR ps_end = ps+len;
01978 while( estr && *estr && (ps < ps_end) )
01979 {
01980 LPXENTITY ent = GetEntity( estr );
01981 if( ent )
01982 {
01983
01984 *ps = ent->entity;
01985 estr += ent->ref_len;
01986 }
01987 else
01988 *ps = *estr++;
01989 ps++;
01990 }
01991 *ps = '\0';
01992
01993
01994 return (ps-str);
01995 }
01996
01997 std::tstring::size_type _tagXMLEntitys::Entity2Ref( LPCTSTR str, std::tstring& estr, int len )
01998 {
01999 std::tstring::size_type nBefore = estr.size();
02000 LPCTSTR str_end = str+len;
02001 while( str && *str && (str < str_end) )
02002 {
02003 LPXENTITY ent = GetEntity( *str );
02004 if( ent )
02005 {
02006
02007 if (ent->ref)
02008 estr += ent->ref;
02009 }
02010 else
02011 estr += *str;
02012 str++;
02013 }
02014
02015
02016 return (estr.size() - nBefore);
02017 }
02018
02019 std::tstring::size_type _tagXMLEntitys::Entity2Ref( LPCTSTR str, LPTSTR estr, int estrlen )
02020 {
02021 LPTSTR pes = (LPTSTR)estr;
02022 LPTSTR pes_end = pes+estrlen;
02023 while( str && *str && (pes < pes_end) )
02024 {
02025 LPXENTITY ent = GetEntity( *str );
02026 if( ent )
02027 {
02028
02029 LPCTSTR ref = ent->ref;
02030 while( ref && *ref )
02031 *pes++ = *ref++;
02032 }
02033 else
02034 *pes++ = *str;
02035 str++;
02036 }
02037 *pes = '\0';
02038
02039
02040 return (pes-estr);
02041 }
02042
02043 std::tstring _tagXMLEntitys::Ref2Entity( LPCTSTR estr )
02044 {
02045 std::tstring es;
02046 if( estr )
02047 {
02048 int len = (int)_tcslen(estr);
02049 Ref2Entity(estr, es, len);
02050 }
02051 return es;
02052 }
02053
02054 std::tstring _tagXMLEntitys::Entity2Ref( LPCTSTR str )
02055 {
02056 std::tstring s;
02057 if( str )
02058 {
02059 int nEntityCount = GetEntityCount(str);
02060 if( nEntityCount == 0 )
02061 return str;
02062 Entity2Ref( str, s, (int)_tcslen(str) );
02063 }
02064 return s;
02065 }
02066
02067 std::tstring XRef2Entity( LPCTSTR estr )
02068 {
02069 return entityDefault.Ref2Entity( estr );
02070 }
02071
02072 std::tstring XEntity2Ref( LPCTSTR str )
02073 {
02074 return entityDefault.Entity2Ref( str );
02075 }