/PROJECTS_ROOT/SmartWires/SystemUtils/xml/XMLite.cpp

http://wiredplane-wintools.googlecode.com/ · C++ · 2238 lines · 1313 code · 170 blank · 755 comment · 405 complexity · c52a3db20397c2f49ca1263ab95f06b3 MD5 · raw file

Large files are truncated click here to view the full file

  1. // XMLite.cpp: implementation of the XMLite class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "XMLite.h"
  6. #ifdef _DEBUG
  7. #undef THIS_FILE
  8. static char THIS_FILE[]=__FILE__;
  9. #define new DEBUG_NEW
  10. #endif
  11. static const TCHAR chXMLTagOpen = '<';
  12. static const TCHAR chXMLTagClose = '>';
  13. static const TCHAR chXMLTagPre = '/';
  14. static const TCHAR chXMLEscape = '\\'; // for value field escape
  15. static const TCHAR szXMLPIOpen[] = _T("<?");
  16. static const TCHAR szXMLPIClose[] = _T("?>");
  17. static const TCHAR szXMLCommentOpen[] = _T("<!--");
  18. static const TCHAR szXMLCommentClose[] = _T("-->");
  19. static const TCHAR szXMLCDATAOpen[] = _T("<![CDATA[");
  20. static const TCHAR szXMLCDATAClose[] = _T("]]>");
  21. static const XENTITY x_EntityTable[] = {
  22. { '&', _T("&amp;"), 5 } ,
  23. { '\"', _T("&quot;"), 6 } ,
  24. { '\'', _T("&apos;"), 6 } ,
  25. { '<', _T("&lt;"), 4 } ,
  26. { '>', _T("&gt;"), 4 }
  27. };
  28. PARSEINFO piDefault;
  29. DISP_OPT optDefault;
  30. XENTITYS entityDefault((LPXENTITY)x_EntityTable, sizeof(x_EntityTable)/sizeof(x_EntityTable[0]) );
  31. //////////////////////////////////////////////////////////////////////
  32. // Construction/Destruction
  33. //////////////////////////////////////////////////////////////////////
  34. //========================================================
  35. // Name : _tcschrs
  36. // Desc : same with _tcspbrk
  37. // Param :
  38. // Return :
  39. //--------------------------------------------------------
  40. // Coder Date Desc
  41. // bro 2002-10-29
  42. //========================================================
  43. LPTSTR _tcschrs( LPCTSTR psz, LPCTSTR pszchs )
  44. {
  45. while( psz && *psz )
  46. {
  47. if( strchr( pszchs, *psz ) )
  48. return (LPTSTR)psz;
  49. psz++;
  50. }
  51. return NULL;
  52. }
  53. //========================================================
  54. // Name : _tcsskip
  55. // Desc : skip space
  56. // Param :
  57. // Return : skiped string
  58. //--------------------------------------------------------
  59. // Coder Date Desc
  60. // bro 2002-10-29
  61. //========================================================
  62. LPTSTR _tcsskip( LPCTSTR psz )
  63. {
  64. //while( psz && *psz == ' ' && *psz == 13 && *psz == 10 ) psz++;
  65. while( psz && isspace(*psz) ) psz++;
  66. return (LPTSTR)psz;
  67. }
  68. //========================================================
  69. // Name : _tcsechr
  70. // Desc : similar with _tcschr with escape process
  71. // Param : escape - will be escape character
  72. // Return :
  73. //--------------------------------------------------------
  74. // Coder Date Desc
  75. // bro 2002-10-29
  76. //========================================================
  77. LPTSTR _tcsechr( LPCTSTR psz, int ch, int escape )
  78. {
  79. LPTSTR pch = (LPTSTR)psz;
  80. while( pch && *pch )
  81. {
  82. if( escape != 0 && *pch == escape )
  83. pch++;
  84. else
  85. if( *pch == ch )
  86. return (LPTSTR)pch;
  87. pch++;
  88. }
  89. return pch;
  90. }
  91. //========================================================
  92. // Name : _tcselen
  93. // Desc : similar with _tcslen with escape process
  94. // Param : escape - will be escape character
  95. // Return :
  96. //--------------------------------------------------------
  97. // Coder Date Desc
  98. // bro 2002-10-29
  99. //========================================================
  100. int _tcselen( int escape, LPTSTR srt, LPTSTR end = NULL )
  101. {
  102. int len = 0;
  103. LPTSTR pch = srt;
  104. if( end==NULL ) end = (LPTSTR)sizeof(long);
  105. LPTSTR prev_escape = NULL;
  106. while( pch && *pch && pch<end )
  107. {
  108. if( escape != 0 && *pch == escape && prev_escape == NULL )
  109. prev_escape = pch;
  110. else
  111. {
  112. prev_escape = NULL;
  113. len++;
  114. }
  115. pch++;
  116. }
  117. return len;
  118. }
  119. //========================================================
  120. // Name : _tcsecpy
  121. // Desc : similar with _tcscpy with escape process
  122. // Param : escape - will be escape character
  123. // Return :
  124. //--------------------------------------------------------
  125. // Coder Date Desc
  126. // bro 2002-10-29
  127. //========================================================
  128. void _tcsecpy( LPTSTR psz, int escape, LPTSTR srt, LPTSTR end = NULL )
  129. {
  130. LPTSTR pch = srt;
  131. if( end==NULL ) end = (LPTSTR)sizeof(long);
  132. LPTSTR prev_escape = NULL;
  133. while( pch && *pch && pch<end )
  134. {
  135. if( escape != 0 && *pch == escape && prev_escape == NULL )
  136. prev_escape = pch;
  137. else
  138. {
  139. prev_escape = NULL;
  140. *psz++ = *pch;
  141. }
  142. pch++;
  143. }
  144. *psz = '\0';
  145. }
  146. //========================================================
  147. // Name : _tcsepbrk
  148. // Desc : similar with _tcspbrk with escape process
  149. // Param : escape - will be escape character
  150. // Return :
  151. //--------------------------------------------------------
  152. // Coder Date Desc
  153. // bro 2002-10-29
  154. //========================================================
  155. LPTSTR _tcsepbrk( LPCTSTR psz, LPCTSTR chset, int escape )
  156. {
  157. LPTSTR pch = (LPTSTR)psz;
  158. LPTSTR prev_escape = NULL;
  159. while( pch && *pch )
  160. {
  161. if( escape != 0 && *pch == escape && prev_escape == NULL )
  162. prev_escape = pch;
  163. else
  164. {
  165. prev_escape = NULL;
  166. if( _tcschr( chset, *pch ) )
  167. return (LPTSTR)pch;
  168. }
  169. pch++;
  170. }
  171. return pch;
  172. }
  173. //========================================================
  174. // Name : _tcsenicmp
  175. // Desc : similar with _tcsnicmp with escape process
  176. // Param : escape - will be escape character
  177. // Return :
  178. //--------------------------------------------------------
  179. // Coder Date Desc
  180. // bro 2002-10-29
  181. //========================================================
  182. int _tcsenicmp( LPCTSTR psz, LPCTSTR str, int len, int escape )
  183. {
  184. LPTSTR pch = (LPTSTR)psz;
  185. LPTSTR prev_escape = NULL;
  186. LPTSTR des = (LPTSTR)str;
  187. int i = 0;
  188. while( pch && *pch && i < len )
  189. {
  190. if( escape != 0 && *pch == escape && prev_escape == NULL )
  191. prev_escape = pch;
  192. else
  193. {
  194. prev_escape = NULL;
  195. if( tolower(*pch) != tolower(des[i]) )
  196. break;
  197. i++;
  198. }
  199. pch ++;
  200. }
  201. // find
  202. if( i == len )
  203. return 0;
  204. if( psz[i] > des[i] )
  205. return 1;
  206. return -1;
  207. }
  208. //========================================================
  209. // Name : _tcsenistr
  210. // Desc : similar with _tcsistr with escape process
  211. // Param : escape - will be escape character
  212. // Return :
  213. //--------------------------------------------------------
  214. // Coder Date Desc
  215. // bro 2002-10-29
  216. //========================================================
  217. LPTSTR _tcsenistr( LPCTSTR psz, LPCTSTR str, int len, int escape )
  218. {
  219. LPTSTR pch = (LPTSTR)psz;
  220. LPTSTR prev_escape = NULL;
  221. LPTSTR des = (LPTSTR)str;
  222. int i = 0;
  223. while( pch && *pch )
  224. {
  225. if( escape != 0 && *pch == escape && prev_escape == NULL )
  226. prev_escape = pch;
  227. else
  228. {
  229. prev_escape = NULL;
  230. if( _tcsenicmp( pch, str, len, escape ) == 0 )
  231. return (LPTSTR)pch;
  232. }
  233. pch++;
  234. }
  235. return pch;
  236. }
  237. //========================================================
  238. // Name : _tcseistr
  239. // Desc : similar with _tcsistr with escape process
  240. // Param : escape - will be escape character
  241. // Return :
  242. //--------------------------------------------------------
  243. // Coder Date Desc
  244. // bro 2002-10-29
  245. //========================================================
  246. LPTSTR _tcseistr( LPCTSTR psz, LPCTSTR str, int escape )
  247. {
  248. int len = _tcslen( str );
  249. return _tcsenistr( psz, str, len, escape );
  250. }
  251. //========================================================
  252. // Name : _SetString
  253. // Desc : put string of (psz~end) on ps string
  254. // Param : trim - will be trim?
  255. // Return :
  256. //--------------------------------------------------------
  257. // Coder Date Desc
  258. // bro 2002-10-29
  259. //========================================================
  260. void _SetString( LPTSTR psz, LPTSTR end, CString* ps, bool trim = FALSE, int escape = 0 )
  261. {
  262. //trim
  263. if( trim )
  264. {
  265. while( psz && psz < end && _istspace(*psz) ) psz++;
  266. while( (end-1) && psz < (end-1) && _istspace(*(end-1)) ) end--;
  267. }
  268. int len = end - psz;
  269. if( len <= 0 ) return;
  270. if( escape )
  271. {
  272. len = _tcselen( escape, psz, end );
  273. LPTSTR pss = ps->GetBufferSetLength( len );
  274. _tcsecpy( pss, escape, psz, end );
  275. }
  276. else
  277. {
  278. LPTSTR pss = ps->GetBufferSetLength(len + 1 );
  279. memcpy( pss, psz, len );
  280. pss[len] = '\0';
  281. }
  282. }
  283. _tagXMLNode::~_tagXMLNode()
  284. {
  285. Close();
  286. }
  287. void _tagXMLNode::Close()
  288. {
  289. int i;
  290. for( i = 0 ; i < childs.size(); i ++)
  291. {
  292. LPXNode p = childs[i];
  293. if( p )
  294. {
  295. delete p; childs[i] = NULL;
  296. }
  297. }
  298. childs.clear();
  299. for( i = 0 ; i < attrs.size(); i ++)
  300. {
  301. LPXAttr p = attrs[i];
  302. if( p )
  303. {
  304. delete p; attrs[i] = NULL;
  305. }
  306. }
  307. attrs.clear();
  308. }
  309. // attr1="value1" attr2='value2' attr3=value3 />
  310. // ^- return pointer
  311. //========================================================
  312. // Name : LoadAttributes
  313. // Desc : loading attribute plain xml text
  314. // Param : pszAttrs - xml of attributes
  315. // pi = parser information
  316. // Return : advanced string pointer. (error return NULL)
  317. //--------------------------------------------------------
  318. // Coder Date Desc
  319. // bro 2002-10-29
  320. //========================================================
  321. LPTSTR _tagXMLNode::LoadAttributes( LPCTSTR pszAttrs , LPPARSEINFO pi /*= &piDefault*/)
  322. {
  323. LPTSTR xml = (LPTSTR)pszAttrs;
  324. while( xml && *xml )
  325. {
  326. if( xml = _tcsskip( xml ) )
  327. {
  328. // close tag
  329. if( *xml == chXMLTagClose || *xml == chXMLTagPre )
  330. // wel-formed tag
  331. return xml;
  332. // XML Attr Name
  333. TCHAR* pEnd = _tcspbrk( xml, " =" );
  334. if( pEnd == NULL )
  335. {
  336. // error
  337. if( pi->erorr_occur == false )
  338. {
  339. pi->erorr_occur = true;
  340. pi->error_pointer = xml;
  341. pi->error_code = PIE_ATTR_NO_VALUE;
  342. pi->error_string.Format( _T("<%s> attribute has error "), name );
  343. }
  344. return NULL;
  345. }
  346. LPXAttr attr = new XAttr;
  347. attr->parent = this;
  348. // XML Attr Name
  349. _SetString( xml, pEnd, &attr->name );
  350. // add new attribute
  351. attrs.push_back( attr );
  352. xml = pEnd;
  353. // XML Attr Value
  354. if( xml = _tcsskip( xml ) )
  355. {
  356. //if( xml = _tcschr( xml, '=' ) )
  357. if( *xml == '=' )
  358. {
  359. if( xml = _tcsskip( ++xml ) )
  360. {
  361. // if " or '
  362. // or none quote
  363. int quote = *xml;
  364. if( quote == '"' || quote == '\'' )
  365. pEnd = _tcsechr( ++xml, quote, chXMLEscape );
  366. else
  367. {
  368. //attr= value>
  369. // none quote mode
  370. //pEnd = _tcsechr( xml, ' ', '\\' );
  371. pEnd = _tcsepbrk( xml, _T(" >"), chXMLEscape );
  372. }
  373. bool trim = pi->trim_value;
  374. TCHAR escape = pi->escape_value;
  375. //_SetString( xml, pEnd, &attr->value, trim, chXMLEscape );
  376. _SetString( xml, pEnd, &attr->value, trim, escape );
  377. xml = pEnd;
  378. // ATTRVALUE
  379. if( pi->entity_value && pi->entitys )
  380. attr->value = pi->entitys->Ref2Entity(attr->value);
  381. if( quote == '"' || quote == '\'' )
  382. xml++;
  383. }
  384. }
  385. }
  386. }
  387. }
  388. // not wel-formed tag
  389. return NULL;
  390. }
  391. // attr1="value1" attr2='value2' attr3=value3 />
  392. // ^- return pointer
  393. //========================================================
  394. // Name : LoadAttributes
  395. // Desc : loading attribute plain xml text
  396. // Param : pszAttrs - xml of attributes
  397. // pszEnd - last string
  398. // pi = parser information
  399. // Return : advanced string pointer. (error return NULL)
  400. //--------------------------------------------------------
  401. // Coder Date Desc
  402. // bro 2004-06-14
  403. //========================================================
  404. LPTSTR _tagXMLNode::LoadAttributes( LPCTSTR pszAttrs, LPCTSTR pszEnd, LPPARSEINFO pi /*= &piDefault*/ )
  405. {
  406. LPTSTR xml = (LPTSTR)pszAttrs;
  407. while( xml && *xml )
  408. {
  409. if( xml = _tcsskip( xml ) )
  410. {
  411. // close tag
  412. if( xml >= pszEnd )
  413. // wel-formed tag
  414. return xml;
  415. // XML Attr Name
  416. TCHAR* pEnd = _tcspbrk( xml, " =" );
  417. if( pEnd == NULL )
  418. {
  419. // error
  420. if( pi->erorr_occur == false )
  421. {
  422. pi->erorr_occur = true;
  423. pi->error_pointer = xml;
  424. pi->error_code = PIE_ATTR_NO_VALUE;
  425. pi->error_string.Format( _T("<%s> attribute has error "), name );
  426. }
  427. return NULL;
  428. }
  429. LPXAttr attr = new XAttr;
  430. attr->parent = this;
  431. // XML Attr Name
  432. _SetString( xml, pEnd, &attr->name );
  433. // add new attribute
  434. attrs.push_back( attr );
  435. xml = pEnd;
  436. // XML Attr Value
  437. if( xml = _tcsskip( xml ) )
  438. {
  439. //if( xml = _tcschr( xml, '=' ) )
  440. if( *xml == '=' )
  441. {
  442. if( xml = _tcsskip( ++xml ) )
  443. {
  444. // if " or '
  445. // or none quote
  446. int quote = *xml;
  447. if( quote == '"' || quote == '\'' )
  448. pEnd = _tcsechr( ++xml, quote, chXMLEscape );
  449. else
  450. {
  451. //attr= value>
  452. // none quote mode
  453. //pEnd = _tcsechr( xml, ' ', '\\' );
  454. pEnd = _tcsepbrk( xml, _T(" >"), chXMLEscape );
  455. }
  456. bool trim = pi->trim_value;
  457. TCHAR escape = pi->escape_value;
  458. //_SetString( xml, pEnd, &attr->value, trim, chXMLEscape );
  459. _SetString( xml, pEnd, &attr->value, trim, escape );
  460. xml = pEnd;
  461. // ATTRVALUE
  462. if( pi->entity_value && pi->entitys )
  463. attr->value = pi->entitys->Ref2Entity(attr->value);
  464. if( quote == '"' || quote == '\'' )
  465. xml++;
  466. }
  467. }
  468. }
  469. }
  470. }
  471. // not wel-formed tag
  472. return NULL;
  473. }
  474. // <?xml version="1.0"?>
  475. // ^- return pointer
  476. //========================================================
  477. // Name : LoadProcessingInstrunction
  478. // Desc : loading processing instruction
  479. // Param : pszXml - PI string
  480. // pi - parser information
  481. // Return : advanced string pointer. (error return NULL)
  482. //--------------------------------------------------------
  483. // Coder Date Desc
  484. // bro 2004-06-14
  485. //========================================================
  486. LPTSTR _tagXMLNode::LoadProcessingInstrunction( LPCTSTR pszXml, LPPARSEINFO pi /*= &piDefault*/ )
  487. {
  488. // find the end of pi
  489. LPTSTR end = _tcsenistr( pszXml, szXMLPIClose, sizeof(szXMLPIClose)-1, pi ? pi->escape_value : 0 );
  490. if( end == NULL )
  491. return NULL;
  492. // process pi
  493. if( doc )
  494. {
  495. LPTSTR xml = (LPTSTR)pszXml;
  496. LPXNode node = new XNode;
  497. node->parent = this;
  498. node->doc = doc;
  499. node->type = XNODE_PI;
  500. xml += sizeof(szXMLPIOpen)-1;
  501. TCHAR* pTagEnd = _tcspbrk( xml, " ?>" );
  502. _SetString( xml, pTagEnd, &node->name );
  503. xml = pTagEnd;
  504. node->LoadAttributes( xml, end, pi );
  505. doc->childs.push_back( node );
  506. }
  507. end += sizeof(szXMLPIClose)-1;
  508. return end;
  509. }
  510. // <!-- comment -->
  511. // ^- return pointer
  512. //========================================================
  513. // Name : LoadComment
  514. // Desc : loading comment
  515. // Param : pszXml - comment string
  516. // pi - parser information
  517. // Return : advanced string pointer. (error return NULL)
  518. //--------------------------------------------------------
  519. // Coder Date Desc
  520. // bro 2004-06-14
  521. //========================================================
  522. LPTSTR _tagXMLNode::LoadComment( LPCTSTR pszXml, LPPARSEINFO pi /*= &piDefault*/ )
  523. {
  524. // find the end of comment
  525. LPTSTR end = _tcsenistr( pszXml, szXMLCommentClose, sizeof(szXMLCommentClose)-1, pi ? pi->escape_value : 0 );
  526. if( end == NULL )
  527. return NULL;
  528. // process comment
  529. LPXNode par = parent;
  530. if( parent == NULL && doc )
  531. par = (LPXNode)&doc;
  532. if( par )
  533. {
  534. LPTSTR xml = (LPTSTR)pszXml;
  535. xml += sizeof(szXMLCommentOpen)-1;
  536. LPXNode node = new XNode;
  537. node->parent = this;
  538. node->doc = doc;
  539. node->type = XNODE_COMMENT;
  540. node->name = _T("#COMMENT");
  541. _SetString( xml, end, &node->value, FALSE );
  542. par->childs.push_back( node );
  543. }
  544. end += sizeof(szXMLCommentClose)-1;
  545. return end;
  546. }
  547. // <![CDATA[ cdata ]]>
  548. // ^- return pointer
  549. //========================================================
  550. // Name : LoadCDATA
  551. // Desc : loading CDATA
  552. // Param : pszXml - CDATA string
  553. // pi - parser information
  554. // Return : advanced string pointer. (error return NULL)
  555. //--------------------------------------------------------
  556. // Coder Date Desc
  557. // bro 2004-06-14
  558. //========================================================
  559. LPTSTR _tagXMLNode::LoadCDATA( LPCTSTR pszXml, LPPARSEINFO pi /*= &piDefault*/ )
  560. {
  561. // find the end of CDATA
  562. LPTSTR end = _tcsenistr( pszXml, szXMLCDATAClose, sizeof(szXMLCDATAClose)-1, pi ? pi->escape_value : 0 );
  563. if( end == NULL )
  564. return NULL;
  565. // process CDATA
  566. LPXNode par = parent;
  567. if( parent == NULL && doc )
  568. par = (LPXNode)&doc;
  569. if( par )
  570. {
  571. LPTSTR xml = (LPTSTR)pszXml;
  572. xml += sizeof(szXMLCDATAOpen)-1;
  573. LPXNode node = new XNode;
  574. node->parent = this;
  575. node->doc = doc;
  576. node->type = XNODE_CDATA;
  577. node->name = _T("#CDATA");
  578. _SetString( xml, end, &node->value, FALSE );
  579. par->childs.push_back( node );
  580. }
  581. end += sizeof(szXMLCDATAClose)-1;
  582. return end;
  583. }
  584. //========================================================
  585. // Name : LoadOtherNodes
  586. // Desc : internal function for loading PI/CDATA/Comment
  587. // Param : node - current xml node
  588. // pbRet - error occur
  589. // pszXml - CDATA string
  590. // pi - parser information
  591. // Return : advanced string pointer. (error return NULL)
  592. //--------------------------------------------------------
  593. // Coder Date Desc
  594. // bro 2004-06-14
  595. //========================================================
  596. LPTSTR LoadOtherNodes( LPXNode node, bool* pbRet, LPCTSTR pszXml, LPPARSEINFO pi /*= &piDefault*/ )
  597. {
  598. LPTSTR xml = (LPTSTR)pszXml;
  599. bool do_other_type = true;
  600. *pbRet = false;
  601. while( xml && do_other_type )
  602. {
  603. do_other_type = false;
  604. xml = _tcsskip( xml );
  605. LPTSTR prev = xml;
  606. // is PI( Processing Instruction ) Node?
  607. if( _tcsnicmp( xml, szXMLPIOpen, sizeof(szXMLPIOpen)-1 ) == 0 )
  608. {
  609. // processing instrunction parse
  610. // return pointer is next node of pi
  611. xml = node->LoadProcessingInstrunction( xml, pi );
  612. //if( xml == NULL )
  613. // return NULL;
  614. // restart xml parse
  615. }
  616. if( xml != prev )
  617. do_other_type = true;
  618. xml = _tcsskip( xml );
  619. prev = xml;
  620. // is comment Node?
  621. if( _tcsnicmp( xml, szXMLCommentOpen, sizeof(szXMLCommentOpen)-1 ) == 0 )
  622. {
  623. // processing comment parse
  624. // return pointer is next node of comment
  625. xml = node->LoadComment( xml, pi );
  626. // comment node is terminal node
  627. if( node->parent && node->parent->type != XNODE_DOC
  628. && xml != prev )
  629. {
  630. *pbRet = true;
  631. return xml;
  632. }
  633. // restart xml parse when this node is root doc node
  634. }
  635. if( xml != prev )
  636. do_other_type = true;
  637. xml = _tcsskip( xml );
  638. prev = xml;
  639. // is CDATA Node?
  640. if( _tcsnicmp( xml, szXMLCDATAOpen, sizeof(szXMLCDATAOpen)-1 ) == 0 )
  641. {
  642. // processing CDATA parse
  643. // return pointer is next node of CDATA
  644. xml = node->LoadCDATA( xml, pi );
  645. // CDATA node is terminal node
  646. if( node->parent && node->parent->type != XNODE_DOC
  647. && xml != prev )
  648. {
  649. *pbRet = true;
  650. return xml;
  651. }
  652. // restart xml parse when this node is root doc node
  653. }
  654. if( xml != prev )
  655. do_other_type = true;
  656. }
  657. return xml;
  658. }
  659. // <TAG attr1="value1" attr2='value2' attr3=value3 >
  660. // </TAG>
  661. // or
  662. // <TAG />
  663. // ^- return pointer
  664. //========================================================
  665. // Name : Load
  666. // Desc : load xml plain text
  667. // Param : pszXml - plain xml text
  668. // pi = parser information
  669. // Return : advanced string pointer (error return NULL)
  670. //--------------------------------------------------------
  671. // Coder Date Desc
  672. // bro 2002-10-29
  673. //========================================================
  674. #define RETURN_XML(var) {iEndPos=(var-pi->startXML);return var;};
  675. LPTSTR _tagXMLNode::Load( LPCTSTR pszXml, LPPARSEINFO pi /*= &piDefault*/ )
  676. {
  677. // Close it
  678. Close();
  679. LPTSTR xml = (LPTSTR)pszXml;
  680. xml = _tcschr( xml, chXMLTagOpen );
  681. if( xml == NULL )
  682. return NULL;
  683. iBeginPos=(xml-pi->startXML);
  684. // Close Tag
  685. if( *(xml+1) == chXMLTagPre ){ // </Close
  686. RETURN_XML(xml);
  687. }
  688. // Load Other Node before <Tag>(pi, comment, CDATA etc)
  689. bool bRet = false;
  690. LPTSTR ret = NULL;
  691. ret = LoadOtherNodes( this, &bRet, xml, pi );
  692. if( ret != NULL )
  693. xml = ret;
  694. if( bRet ) {
  695. RETURN_XML(xml);
  696. }
  697. // XML Node Tag Name Open
  698. xml++;
  699. TCHAR* pTagEnd = _tcspbrk( xml, " />\t\r\n" );
  700. _SetString( xml, pTagEnd, &name );
  701. xml = pTagEnd;
  702. // Generate XML Attributte List
  703. if( xml = LoadAttributes( xml, pi ) )
  704. {
  705. // alone tag <TAG ... />
  706. if( *xml == chXMLTagPre )
  707. {
  708. xml++;
  709. if( *xml == chXMLTagClose ){
  710. // wel-formed tag
  711. ++xml;
  712. RETURN_XML(xml);
  713. }else
  714. {
  715. // error: <TAG ... / >
  716. if( pi->erorr_occur == false )
  717. {
  718. pi->erorr_occur = true;
  719. pi->error_pointer = xml;
  720. pi->error_code = PIE_ALONE_NOT_CLOSED;
  721. pi->error_string = _T("Element must be closed.");
  722. }
  723. // not wel-formed tag
  724. return NULL;
  725. }
  726. }
  727. else
  728. // open/close tag <TAG ..> ... </TAG>
  729. // ^- current pointer
  730. {
  731. // if text value is not exist, then assign value
  732. //if( this->value.IsEmpty() || this->value == _T("") )
  733. if( XIsEmptyString( value ) )
  734. {
  735. // Text Value
  736. TCHAR* pEnd = _tcsechr( ++xml, chXMLTagOpen, chXMLEscape );
  737. if( pEnd == NULL )
  738. {
  739. if( pi->erorr_occur == false )
  740. {
  741. pi->erorr_occur = true;
  742. pi->error_pointer = xml;
  743. pi->error_code = PIE_NOT_CLOSED;
  744. pi->error_string.Format(_T("%s must be closed with </%s>"), name );
  745. }
  746. // error cos not exist CloseTag </TAG>
  747. return NULL;
  748. }
  749. bool trim = pi->trim_value;
  750. TCHAR escape = pi->escape_value;
  751. //_SetString( xml, pEnd, &value, trim, chXMLEscape );
  752. _SetString( xml, pEnd, &value, trim, escape );
  753. xml = pEnd;
  754. // TEXTVALUE reference
  755. if( pi->entity_value && pi->entitys )
  756. value = pi->entitys->Ref2Entity(value);
  757. }
  758. // generate child nodes
  759. while( xml && *xml )
  760. {
  761. LPXNode node = new XNode;
  762. node->parent = this;
  763. node->doc = doc;
  764. node->type = type;
  765. xml = node->Load( xml,pi );
  766. if( node->name.IsEmpty() == FALSE )
  767. {
  768. childs.push_back( node );
  769. }
  770. else
  771. {
  772. delete node;
  773. }
  774. // open/close tag <TAG ..> ... </TAG>
  775. // ^- current pointer
  776. // CloseTag case
  777. if( xml && *xml && *(xml+1) && *xml == chXMLTagOpen && *(xml+1) == chXMLTagPre )
  778. {
  779. // </Close>
  780. xml+=2; // C
  781. if( xml = _tcsskip( xml ) )
  782. {
  783. CString closename;
  784. TCHAR* pEnd = _tcspbrk( xml, " >" );
  785. if( pEnd == NULL )
  786. {
  787. if( pi->erorr_occur == false )
  788. {
  789. pi->erorr_occur = true;
  790. pi->error_pointer = xml;
  791. pi->error_code = PIE_NOT_CLOSED;
  792. pi->error_string.Format(_T("it must be closed with </%s>"), name );
  793. }
  794. // error
  795. return NULL;
  796. }
  797. _SetString( xml, pEnd, &closename );
  798. if( closename == this->name )
  799. {
  800. // wel-formed open/close
  801. xml = pEnd+1;
  802. // return '>' or ' ' after pointer
  803. RETURN_XML(xml);
  804. }
  805. else
  806. {
  807. xml = pEnd+1;
  808. // 2004.6.15 - example <B> alone tag
  809. // now it can parse with attribute 'force_arse'
  810. if( pi->force_parse == false )
  811. {
  812. // not welformed open/close
  813. if( pi->erorr_occur == false )
  814. {
  815. pi->erorr_occur = true;
  816. pi->error_pointer = xml;
  817. pi->error_code = PIE_NOT_NESTED;
  818. pi->error_string.Format(_T("'<%s> ... </%s>' is not wel-formed."), name, closename );
  819. }
  820. return NULL;
  821. }
  822. }
  823. }
  824. }
  825. else // Alone child Tag Loaded
  826. // else Ç?žßÇ?´ÂÁö ¸?ž?žßÇ?´ÂÁö ?Ç?ɰ?´?.
  827. {
  828. //if( xml && this->value.IsEmpty() && *xml !=chXMLTagOpen )
  829. if( xml && XIsEmptyString( value ) && *xml !=chXMLTagOpen )
  830. {
  831. // Text Value
  832. TCHAR* pEnd = _tcsechr( xml, chXMLTagOpen, chXMLEscape );
  833. if( pEnd == NULL )
  834. {
  835. // error cos not exist CloseTag </TAG>
  836. if( pi->erorr_occur == false )
  837. {
  838. pi->erorr_occur = true;
  839. pi->error_pointer = xml;
  840. pi->error_code = PIE_NOT_CLOSED;
  841. pi->error_string.Format(_T("it must be closed with </%s>"), name );
  842. }
  843. return NULL;
  844. }
  845. bool trim = pi->trim_value;
  846. TCHAR escape = pi->escape_value;
  847. //_SetString( xml, pEnd, &value, trim, chXMLEscape );
  848. _SetString( xml, pEnd, &value, trim, escape );
  849. xml = pEnd;
  850. //TEXTVALUE
  851. if( pi->entity_value && pi->entitys )
  852. value = pi->entitys->Ref2Entity(value);
  853. }
  854. }
  855. }
  856. }
  857. }
  858. RETURN_XML(xml);
  859. }
  860. // <?xml version='1.0'?>
  861. // <TAG attr1="value1" attr2='value2' attr3=value3 >
  862. // </TAG>
  863. // or
  864. // <TAG />
  865. // ^- return pointer
  866. //========================================================
  867. // Name : Load
  868. // Desc : load xml plain text for xml document
  869. // Param : pszXml - plain xml text
  870. // pi = parser information
  871. // Return : advanced string pointer (error return NULL)
  872. //--------------------------------------------------------
  873. // Coder Date Desc
  874. // bro 2002-10-29
  875. //========================================================
  876. LPTSTR _tagXMLDocument::Load( LPCTSTR pszXml, LPPARSEINFO pi /*= NULL*/ )
  877. {
  878. LPXNode node = new XNode;
  879. node->parent = (LPXNode)this;
  880. node->type = XNODE_ELEMENT;
  881. node->doc = this;
  882. LPTSTR end;
  883. if( pi == NULL ){
  884. pi = &parse_info;
  885. }
  886. pi->startXML=pszXml;
  887. if( (end = node->Load( pszXml, pi )) == NULL )
  888. {
  889. delete node;
  890. return NULL;
  891. }
  892. childs.push_back( node );
  893. // Load Other Node after </Tag>(pi, comment, CDATA etc)
  894. LPTSTR ret;
  895. bool bRet = false;
  896. ret = LoadOtherNodes( node, &bRet, end, pi );
  897. if( ret != NULL )
  898. end = ret;
  899. return end;
  900. }
  901. LPXNode _tagXMLDocument::GetRoot()
  902. {
  903. XNodes::iterator it = childs.begin();
  904. for( ; it != childs.end() ; ++(it) )
  905. {
  906. LPXNode node = *it;
  907. if( node->type == XNODE_ELEMENT )
  908. return node;
  909. }
  910. return NULL;
  911. }
  912. //========================================================
  913. // Name : GetXML
  914. // Desc : convert plain xml text from parsed xml attirbute
  915. // Param :
  916. // Return : converted plain string
  917. //--------------------------------------------------------
  918. // Coder Date Desc
  919. // bro 2002-10-29
  920. //========================================================
  921. CString _tagXMLAttr::GetXML( LPDISP_OPT opt /*= &optDefault*/ )
  922. {
  923. std::ostringstream os;
  924. //os << (LPCTSTR)name << "='" << (LPCTSTR)value << "' ";
  925. os << (LPCTSTR)name << "=" << (char)opt->value_quotation_mark
  926. << (LPCTSTR)(opt->reference_value&&opt->entitys?opt->entitys->Entity2Ref(value):value)
  927. << (char)opt->value_quotation_mark << " ";
  928. return os.str().c_str();
  929. }
  930. //========================================================
  931. // Name : GetXML
  932. // Desc : convert plain xml text from parsed xml node
  933. // Param :
  934. // Return : converted plain string
  935. //--------------------------------------------------------
  936. // Coder Date Desc
  937. // bro 2002-10-29
  938. //========================================================
  939. CString _tagXMLNode::GetXML( LPDISP_OPT opt /*= &optDefault*/ )
  940. {
  941. std::ostringstream os;
  942. // tab
  943. if( opt && opt->newline )
  944. {
  945. if( opt && opt->newline )
  946. os << "\r\n";
  947. for( int i = 0 ; i < opt->tab_base ; i++)
  948. os << '\t';
  949. }
  950. if( type == XNODE_DOC )
  951. {
  952. for( int i = 0 ; i < childs.size(); i++ )
  953. os << (LPCTSTR)childs[i]->GetXML( opt );
  954. return os.str().c_str();
  955. }
  956. else
  957. if( type == XNODE_PI )
  958. {
  959. // <?TAG
  960. os << szXMLPIOpen << (LPCTSTR)name;
  961. // <?TAG Attr1="Val1"
  962. if( attrs.empty() == false ) os << ' ';
  963. for( int i = 0 ; i < attrs.size(); i++ )
  964. {
  965. os << (LPCTSTR)attrs[i]->GetXML(opt);
  966. }
  967. //?>
  968. os << szXMLPIClose;
  969. return os.str().c_str();
  970. }
  971. else
  972. if( type == XNODE_COMMENT )
  973. {
  974. // <--comment
  975. os << szXMLCommentOpen << (LPCTSTR)value;
  976. //-->
  977. os << szXMLCommentClose;
  978. return os.str().c_str();
  979. }
  980. else
  981. if( type == XNODE_CDATA )
  982. {
  983. // <--comment
  984. os << szXMLCDATAOpen << (LPCTSTR)value;
  985. //-->
  986. os << szXMLCDATAClose;
  987. return os.str().c_str();
  988. }
  989. // <TAG
  990. os << '<' << (LPCTSTR)name;
  991. // <TAG Attr1="Val1"
  992. if( attrs.empty() == false ) os << ' ';
  993. for( int i = 0 ; i < attrs.size(); i++ )
  994. {
  995. os << (LPCTSTR)attrs[i]->GetXML(opt);
  996. }
  997. if( childs.empty() && value.IsEmpty() )
  998. {
  999. // <TAG Attr1="Val1"/> alone tag
  1000. os << "/>";
  1001. }
  1002. else
  1003. {
  1004. // <TAG Attr1="Val1"> and get child
  1005. os << '>';
  1006. if( opt && opt->newline && !childs.empty() )
  1007. {
  1008. opt->tab_base++;
  1009. }
  1010. for( int i = 0 ; i < childs.size(); i++ )
  1011. os << (LPCTSTR)childs[i]->GetXML( opt );
  1012. // Text Value
  1013. if( value != _T("") )
  1014. {
  1015. if( opt && opt->newline && !childs.empty() )
  1016. {
  1017. if( opt && opt->newline )
  1018. os << "\r\n";
  1019. for( int i = 0 ; i < opt->tab_base ; i++)
  1020. os << '\t';
  1021. }
  1022. os << (LPCTSTR)(opt->reference_value&&opt->entitys?opt->entitys->Entity2Ref(value):value);
  1023. }
  1024. // </TAG> CloseTag
  1025. if( opt && opt->newline && !childs.empty() )
  1026. {
  1027. os << "\r\n";
  1028. for( int i = 0 ; i < opt->tab_base-1 ; i++)
  1029. os << '\t';
  1030. }
  1031. os << "</" << (LPCTSTR)name << '>';
  1032. if( opt && opt->newline )
  1033. {
  1034. if( !childs.empty() )
  1035. opt->tab_base--;
  1036. }
  1037. }
  1038. return os.str().c_str();
  1039. }
  1040. //========================================================
  1041. // ÇÔ?ö¸í : GetText
  1042. // ?? ¸í : ?ë?? Ç???¸? ?????Ž šŽ?Ú?­?Î šÝ??
  1043. // ?Î ?Ú :
  1044. // ¸Ž??°? : ?????? šŽ?Ú?­
  1045. //--------------------------------------------------------
  1046. // ?????Ú ?????? ????????
  1047. // Á?°?šÎ 2004-06-15
  1048. //========================================================
  1049. CString _tagXMLNode::GetText( LPDISP_OPT opt /*= &optDefault*/ )
  1050. {
  1051. std::ostringstream os;
  1052. if( type == XNODE_DOC )
  1053. {
  1054. for( int i = 0 ; i < childs.size(); i++ )
  1055. os << (LPCTSTR)childs[i]->GetText( opt );
  1056. }
  1057. else
  1058. if( type == XNODE_PI )
  1059. {
  1060. // no text
  1061. }
  1062. else
  1063. if( type == XNODE_COMMENT )
  1064. {
  1065. // no text
  1066. }
  1067. else
  1068. if( type == XNODE_CDATA )
  1069. {
  1070. os << (LPCTSTR)value;
  1071. }
  1072. else
  1073. if( type == XNODE_ELEMENT )
  1074. {
  1075. if( childs.empty() && value.IsEmpty() )
  1076. {
  1077. // no text
  1078. }
  1079. else
  1080. {
  1081. // childs text
  1082. for( int i = 0 ; i < childs.size(); i++ )
  1083. os << (LPCTSTR)childs[i]->GetText();
  1084. // Text Value
  1085. os << (LPCTSTR)(opt->reference_value&&opt->entitys?opt->entitys->Entity2Ref(value):value);
  1086. }
  1087. }
  1088. return os.str().c_str();
  1089. }
  1090. //========================================================
  1091. // Name : GetAttr
  1092. // Desc : get attribute with attribute name
  1093. // Param :
  1094. // Return :
  1095. //--------------------------------------------------------
  1096. // Coder Date Desc
  1097. // bro 2002-10-29
  1098. //========================================================
  1099. LPXAttr _tagXMLNode::GetAttr( LPCTSTR attrname )
  1100. {
  1101. for( int i = 0 ; i < attrs.size(); i++ )
  1102. {
  1103. LPXAttr attr = attrs[i];
  1104. if( attr )
  1105. {
  1106. if( attr->name == attrname )
  1107. return attr;
  1108. }
  1109. }
  1110. return NULL;
  1111. }
  1112. //========================================================
  1113. // Name : GetAttrs
  1114. // Desc : find attributes with attribute name, return its list
  1115. // Param :
  1116. // Return :
  1117. //--------------------------------------------------------
  1118. // Coder Date Desc
  1119. // bro 2002-10-29
  1120. //========================================================
  1121. XAttrs _tagXMLNode::GetAttrs( LPCTSTR name )
  1122. {
  1123. XAttrs attrs;
  1124. for( int i = 0 ; i < attrs.size(); i++ )
  1125. {
  1126. LPXAttr attr = attrs[i];
  1127. if( attr )
  1128. {
  1129. if( attr->name == name )
  1130. attrs.push_back( attr );
  1131. }
  1132. }
  1133. return attrs;
  1134. }
  1135. //========================================================
  1136. // Name : GetAttrValue
  1137. // Desc : get attribute with attribute name, return its value
  1138. // Param :
  1139. // Return :
  1140. //--------------------------------------------------------
  1141. // Coder Date Desc
  1142. // bro 2002-10-29
  1143. //========================================================
  1144. LPCTSTR _tagXMLNode::GetAttrValue( LPCTSTR attrname )
  1145. {
  1146. LPXAttr attr = GetAttr( attrname );
  1147. return attr ? (LPCTSTR)attr->value : NULL;
  1148. }
  1149. XNodes _tagXMLNode::GetChilds()
  1150. {
  1151. return childs;
  1152. }
  1153. //========================================================
  1154. // Name : GetChilds
  1155. // Desc : Find childs with name and return childs list
  1156. // Param :
  1157. // Return :
  1158. //--------------------------------------------------------
  1159. // Coder Date Desc
  1160. // bro 2002-10-29
  1161. //========================================================
  1162. XNodes _tagXMLNode::GetChilds( LPCTSTR name )
  1163. {
  1164. XNodes nodes;
  1165. for( int i = 0 ; i < childs.size(); i++ )
  1166. {
  1167. LPXNode node = childs[i];
  1168. if( node )
  1169. {
  1170. if( node->name == name )
  1171. nodes.push_back( node );
  1172. }
  1173. }
  1174. return nodes;
  1175. }
  1176. //========================================================
  1177. // Name : GetChild
  1178. // Desc : get child node with index
  1179. // Param :
  1180. // Return : NULL return if no child.
  1181. //--------------------------------------------------------
  1182. // Coder Date Desc
  1183. // bro 2002-10-29
  1184. //========================================================
  1185. LPXNode _tagXMLNode::GetChild( int i )
  1186. {
  1187. if( i >= 0 && i < childs.size() )
  1188. return childs[i];
  1189. return NULL;
  1190. }
  1191. //========================================================
  1192. // Name : GetChildCount
  1193. // Desc : get child node count
  1194. // Param :
  1195. // Return : 0 return if no child
  1196. //--------------------------------------------------------
  1197. // Coder Date Desc
  1198. // bro 2002-12-26
  1199. //========================================================
  1200. int _tagXMLNode::GetChildCount()
  1201. {
  1202. return childs.size();
  1203. }
  1204. //========================================================
  1205. // Name : GetChild
  1206. // Desc : Find child with name and return child
  1207. // Param :
  1208. // Return : NULL return if no child.
  1209. //--------------------------------------------------------
  1210. // Coder Date Desc
  1211. // bro 2002-10-29
  1212. //========================================================
  1213. LPXNode _tagXMLNode::GetChild( LPCTSTR name, BOOL bSafe)
  1214. {
  1215. for( int i = 0 ; i < childs.size(); i++ )
  1216. {
  1217. LPXNode node = childs[i];
  1218. if( node )
  1219. {
  1220. if( node->name == name )
  1221. return node;
  1222. }
  1223. }
  1224. // ???ö.íóë?âîé íîä!
  1225. return bSafe?GetEmptyNode():0;
  1226. }
  1227. LPXNode GetEmptyNode()
  1228. {
  1229. static XNode empty;
  1230. return &empty;
  1231. }
  1232. //========================================================
  1233. // Name : GetChildValue
  1234. // Desc : Find child with name and return child's value
  1235. // Param :
  1236. // Return : NULL return if no child.
  1237. //--------------------------------------------------------
  1238. // Coder Date Desc
  1239. // bro 2002-10-29
  1240. //========================================================
  1241. LPCTSTR _tagXMLNode::GetChildValue( LPCTSTR name )
  1242. {
  1243. LPXNode node = GetChild( name );
  1244. return (node != NULL)? (LPCTSTR)node->value : NULL;
  1245. }
  1246. CString _tagXMLNode::GetChildText( LPCTSTR name, LPDISP_OPT opt /*= &optDefault*/ )
  1247. {
  1248. LPXNode node = GetChild( name );
  1249. return (node != NULL)? node->GetText(opt) : _T("");
  1250. }
  1251. LPXAttr _tagXMLNode::GetChildAttr( LPCTSTR name, LPCTSTR attrname )
  1252. {
  1253. LPXNode node = GetChild(name);
  1254. return node ? node->GetAttr(attrname) : NULL;
  1255. }
  1256. LPCTSTR _tagXMLNode::GetChildAttrValue( LPCTSTR name, LPCTSTR attrname )
  1257. {
  1258. LPXAttr attr = GetChildAttr( name, attrname );
  1259. return attr ? (LPCTSTR)attr->value : NULL;
  1260. }
  1261. //========================================================
  1262. // Name : Find
  1263. // Desc : find node with tag name from it's all childs
  1264. // Param :
  1265. // Return : NULL return if no found node.
  1266. //--------------------------------------------------------
  1267. // Coder Date Desc
  1268. // bro 2002-10-29
  1269. //========================================================
  1270. LPXNode _tagXMLNode::Find( LPCTSTR name )
  1271. {
  1272. XNodes::iterator it = childs.begin();
  1273. for( ; it != childs.end(); ++(it))
  1274. {
  1275. LPXNode child = *it;
  1276. if( child->name == name )
  1277. return child;
  1278. XNodes::iterator it = child->childs.begin();
  1279. for( ; it != child->childs.end(); ++(it))
  1280. {
  1281. LPXNode find = child->Find( name );
  1282. if( find != NULL )
  1283. return find;
  1284. }
  1285. }
  1286. return NULL;
  1287. }
  1288. //========================================================
  1289. // Name : GetChildIterator
  1290. // Desc : get child nodes iterator
  1291. // Param :
  1292. // Return : NULL return if no childs.
  1293. //--------------------------------------------------------
  1294. // Coder Date Desc
  1295. // bro 2002-10-29
  1296. //========================================================
  1297. XNodes::iterator _tagXMLNode::GetChildIterator( LPXNode node )
  1298. {
  1299. XNodes::iterator it = childs.begin();
  1300. for( ; it != childs.end() ; ++(it) )
  1301. {
  1302. if( *it == node )
  1303. return it;
  1304. }
  1305. return XNodes::iterator();
  1306. }
  1307. //========================================================
  1308. // Name : AppendChild
  1309. // Desc : add node
  1310. // Param :
  1311. // Return :
  1312. //--------------------------------------------------------
  1313. // Coder Date Desc
  1314. // bro 2002-10-29
  1315. //========================================================
  1316. LPXNode _tagXMLNode::AppendChild( LPCTSTR name /*= NULL*/, LPCTSTR value /*= NULL*/ )
  1317. {
  1318. return AppendChild( CreateNode( name, value ) );
  1319. }
  1320. //========================================================
  1321. // Name : AppendChild
  1322. // Desc : add node
  1323. // Param :
  1324. // Return :
  1325. //--------------------------------------------------------
  1326. // Coder Date Desc
  1327. // bro 2002-10-29
  1328. //========================================================
  1329. LPXNode _tagXMLNode::AppendChild( LPXNode node )
  1330. {
  1331. node->parent = this;
  1332. node->doc = doc;
  1333. childs.push_back( node );
  1334. return node;
  1335. }
  1336. //========================================================
  1337. // Name : RemoveChild
  1338. // Desc : detach node and delete object
  1339. // Param :
  1340. // Return :
  1341. //--------------------------------------------------------
  1342. // Coder Date Desc
  1343. // bro 2002-10-29
  1344. //========================================================
  1345. bool _tagXMLNode::RemoveChild( LPXNode node )
  1346. {
  1347. XNodes::iterator it = GetChildIterator( node );
  1348. if( (*it)!=NULL )
  1349. {
  1350. delete *it;
  1351. childs.erase( it );
  1352. return true;
  1353. }
  1354. return false;
  1355. }
  1356. //========================================================
  1357. // Name : GetAttr
  1358. // Desc : get attribute with index in attribute list
  1359. // Param :
  1360. // Return :
  1361. //--------------------------------------------------------
  1362. // Coder Date Desc
  1363. // bro 2002-10-29
  1364. //========================================================
  1365. LPXAttr _tagXMLNode::GetAttr( int i )
  1366. {
  1367. if( i >= 0 && i < attrs.size() )
  1368. return attrs[i];
  1369. return NULL;
  1370. }
  1371. //========================================================
  1372. // Name : GetAttrIterator
  1373. // Desc : get attribute iterator
  1374. // Param :
  1375. // Return : std::vector<LPXAttr>::iterator
  1376. //--------------------------------------------------------
  1377. // Coder Date Desc
  1378. // bro 2002-10-29
  1379. //========================================================
  1380. XAttrs::iterator _tagXMLNode::GetAttrIterator( LPXAttr attr )
  1381. {
  1382. XAttrs::iterator it = attrs.begin();
  1383. for( ; it != attrs.end() ; ++(it) )
  1384. {
  1385. if( *it == attr )
  1386. return it;
  1387. }
  1388. return XAttrs::iterator();
  1389. }
  1390. //========================================================
  1391. // Name : AppendAttr
  1392. // Desc : add attribute
  1393. // Param :
  1394. // Return :
  1395. //--------------------------------------------------------
  1396. // Coder Date Desc
  1397. // bro 2002-10-29
  1398. //========================================================
  1399. LPXAttr _tagXMLNode::AppendAttr( LPXAttr attr )
  1400. {
  1401. attr->parent = this;
  1402. attrs.push_back( attr );
  1403. return attr;
  1404. }
  1405. //========================================================
  1406. // Name : RemoveAttr
  1407. // Desc : detach attribute and delete object
  1408. // Param :
  1409. // Return :
  1410. //--------------------------------------------------------
  1411. // Coder Date Desc
  1412. // bro 2002-10-29
  1413. //========================================================
  1414. bool _tagXMLNode::RemoveAttr( LPXAttr attr )
  1415. {
  1416. XAttrs::iterator it = GetAttrIterator( attr );
  1417. if( (*it)!=NULL )
  1418. {
  1419. delete *it;
  1420. attrs.erase( it );
  1421. return true;
  1422. }
  1423. return false;
  1424. }
  1425. //========================================================
  1426. // Name : CreateNode
  1427. // Desc : Create node object and return it
  1428. // Param :
  1429. // Return :
  1430. //--------------------------------------------------------
  1431. // Coder Date Desc
  1432. // bro 2002-10-29
  1433. //========================================================
  1434. LPXNode _tagXMLNode::CreateNode( LPCTSTR name /*= NULL*/, LPCTSTR value /*= NULL*/ )
  1435. {
  1436. LPXNode node = new XNode;
  1437. node->name = name;
  1438. node->value = value;
  1439. return node;
  1440. }
  1441. //========================================================
  1442. // Name : CreateAttr
  1443. // Desc : create Attribute object and return it
  1444. // Param :
  1445. // Return :
  1446. //--------------------------------------------------------
  1447. // Coder Date Desc
  1448. // bro 2002-10-29
  1449. //========================================================
  1450. LPXAttr _tagXMLNode::CreateAttr( LPCTSTR name /*= NULL*/, LPCTSTR value /*= NULL*/ )
  1451. {
  1452. LPXAttr attr = new XAttr;
  1453. attr->name = name;
  1454. attr->value = value;
  1455. return attr;
  1456. }
  1457. //========================================================
  1458. // Name : AppendAttr
  1459. // Desc : add attribute
  1460. // Param :
  1461. // Return :
  1462. //--------------------------------------------------------
  1463. // Coder Date Desc
  1464. // bro 2002-10-29
  1465. //========================================================
  1466. LPXAttr _tagXMLNode::AppendAttr( LPCTSTR name /*= NULL*/, LPCTSTR value /*= NULL*/ )
  1467. {
  1468. return AppendAttr( CreateAttr( name, value ) );
  1469. }
  1470. //========================================================
  1471. // Name : DetachChild
  1472. // Desc : no delete object, just detach in list
  1473. // Param :
  1474. // Return :
  1475. //--------------------------------------------------------
  1476. // Coder Date Desc
  1477. // bro 2002-10-29
  1478. //========================================================
  1479. LPXNode _tagXMLNode::DetachChild( LPXNode node )
  1480. {
  1481. XNodes::iterator it = GetChildIterator( node );
  1482. if( (*it)!=NULL )
  1483. {
  1484. childs.erase( it );
  1485. return node;
  1486. }
  1487. return (LPXNode)NULL;
  1488. }
  1489. //========================================================
  1490. // Name : DetachAttr
  1491. // Desc : no delete object, just detach in list
  1492. // Param :
  1493. // Return :
  1494. //--------------------------------------------------------
  1495. // Coder Date Desc
  1496. // bro 2002-10-29
  1497. //========================================================
  1498. LPXAttr _tagXMLNode::DetachAttr( LPXAttr attr )
  1499. {
  1500. XAttrs::iterator it = GetAttrIterator( attr );
  1501. if( (*it)!=NULL )
  1502. {
  1503. attrs.erase( it );
  1504. return attr;
  1505. }
  1506. return (LPXAttr)NULL;
  1507. }
  1508. //========================================================
  1509. // Name : CopyNode
  1510. // Desc : copy current level node with own attributes
  1511. // Param :
  1512. // Return :
  1513. //--------------------------------------------------------
  1514. // Coder Date Desc
  1515. // bro 2002-10-29
  1516. //========================================================
  1517. void _tagXMLNode::CopyNode( LPXNode node )
  1518. {
  1519. Close();
  1520. doc = node->doc;
  1521. parent = node->parent;
  1522. name = node->name;
  1523. value = node->value;
  1524. type = node->type;
  1525. // copy attributes
  1526. for( int i = 0 ; i < node->attrs.size(); i++)
  1527. {
  1528. LPXAttr attr = node->attrs[i];
  1529. if( attr )
  1530. AppendAttr( attr->name, attr->value );
  1531. }
  1532. }
  1533. //========================================================
  1534. // Name : _CopyBranch
  1535. // Desc : recursive internal copy branch
  1536. // Param :
  1537. // Return :
  1538. //--------------------------------------------------------
  1539. // Coder Date Desc
  1540. // bro 2002-10-29
  1541. //========================================================
  1542. void _tagXMLNode::_CopyBranch( LPXNode node )
  1543. {
  1544. CopyNode( node );
  1545. for( int i = 0 ; i < node->childs.size(); i++)
  1546. {
  1547. LPXNode child = node->childs[i];
  1548. if( child )
  1549. {
  1550. LPXNode mychild = new XNode;
  1551. mychild->CopyNode( child );
  1552. AppendChild( mychild );
  1553. mychild->_CopyBranch( child );
  1554. }
  1555. }
  1556. }
  1557. //========================================================
  1558. // Name : AppendChildBranch
  1559. // Desc : add child branch ( deep-copy )
  1560. // Param :
  1561. // Return :
  1562. //--------------------------------------------------------
  1563. // Coder Date Desc
  1564. // bro 2002-10-29
  1565. //========================================================
  1566. LPXNode _tagXMLNode::AppendChildBranch( LPXNode node )
  1567. {
  1568. LPXNode child = new XNode;
  1569. child->CopyBranch( node );
  1570. return AppendChild( child );
  1571. }
  1572. //========================================================
  1573. // Name : CopyBranch
  1574. // Desc : copy branch ( deep-copy )
  1575. // Param :
  1576. // Return :
  1577. //--------------------------------------------------------
  1578. // Coder Date Desc
  1579. // bro 2002-10-29
  1580. //========================================================
  1581. void _tagXMLNode::CopyBranch( LPXNode branch )
  1582. {
  1583. Close();
  1584. _CopyBranch( branch );
  1585. }
  1586. int _tagXMLNode::FindByTagName(LPCTSTR name, BOOL bRecursive, CXMLNodes& sRes)
  1587. {
  1588. XNodes::iterator it = childs.begin();
  1589. for( ; it != childs.end(); ++(it))
  1590. {
  1591. LPXNode child = *it;
  1592. if( child->name == name ){
  1593. sRes.Add(child);
  1594. }
  1595. if(bRecursive){
  1596. XNodes::iterator it = child->childs.begin();
  1597. for( ; it != child->childs.end(); ++(it)){
  1598. child->FindByTagName(name,bRecursive,sRes);
  1599. }
  1600. }
  1601. }
  1602. return sRes.GetSize();
  1603. };
  1604. _tagXMLEntitys::_tagXMLEntitys( LPXENTITY entities, int count )
  1605. {
  1606. for( int i = 0; i < count; i++)
  1607. push_back( entities[i] );
  1608. }
  1609. LPXENTITY _tagXMLEntitys::GetEntity( int entity )
  1610. {
  1611. for( int i = 0 ; i < size(); i ++ )
  1612. {
  1613. if( at(i).entity == entity )
  1614. return LPXENTITY(&at(i));
  1615. }
  1616. return NULL;
  1617. }
  1618. LPXENTITY _tagXMLEntitys::GetEntity( LPTSTR entity )
  1619. {
  1620. for( int i = 0 ; i < size(); i ++ )
  1621. {
  1622. LPTSTR ref = (LPTSTR)at(i).ref;
  1623. LPTSTR ps = entity;
  1624. while( ref && *ref )
  1625. if( *ref++ != *ps++ )
  1626. break;
  1627. if( ref && !*ref ) // found!
  1628. return LPXENTITY(&at(i));
  1629. }
  1630. return NULL;
  1631. }
  1632. int _tagXMLEntitys::GetEntityCount( LPCTSTR str )
  1633. {
  1634. int nCount = 0;
  1635. LPTSTR ps = (LPTSTR)str;
  1636. while( ps && *ps )
  1637. if( GetEntity( *ps++ ) ) nCount ++;
  1638. return nCount;
  1639. }
  1640. int _tagXMLEntitys::Ref2Entity( LPCTSTR estr, LPTSTR str, int strlen )
  1641. {
  1642. LPTSTR pes = (LPTSTR)estr;
  1643. LPTSTR ps = str;
  1644. LPTSTR ps_end = ps+strlen;
  1645. while( pes && *pes && ps < ps_end )
  1646. {
  1647. LPXENTITY ent = GetEntity( pes );
  1648. if( ent )
  1649. {
  1650. // copy entity meanning char
  1651. *ps = ent->entity;
  1652. pes += ent->ref_len;
  1653. }
  1654. else
  1655. *ps = *pes++; // default character copy
  1656. ps++;
  1657. }
  1658. *ps = '\0';
  1659. // total copied characters
  1660. return ps-str;
  1661. }
  1662. int _tagXMLEntitys::Entity2Ref( LPCTSTR str, LPTSTR estr, int estrlen )
  1663. {
  1664. LPTSTR ps = (LPTSTR)str;
  1665. LPTSTR pes = (LPTSTR)estr;
  1666. LPTSTR pes_end = pes+estrlen;
  1667. while( ps && *ps && pes < pes_end )
  1668. {
  1669. LPXENTITY ent = GetEntity( *ps );
  1670. if( ent )
  1671. {
  1672. // copy entity string
  1673. LPTSTR ref = (LPTSTR)ent->ref;
  1674. while( ref && *ref )
  1675. *pes++ = *ref++;
  1676. }
  1677. else
  1678. *pes++ = *ps; // default character copy
  1679. ps++;
  1680. }
  1681. *pes = '\0';
  1682. // total copied characters
  1683. return pes-estr;
  1684. }
  1685. CString _tagXMLEntitys::Ref2Entity( LPCTSTR estr )
  1686. {
  1687. CString es;
  1688. if( estr )
  1689. {
  1690. int len = _tcslen(estr);
  1691. LPTSTR esbuf = es.GetBufferSetLength( len+1 );
  1692. if( esbuf )
  1693. Ref2Entity( estr, esbuf, len );
  1694. }
  1695. return es;
  1696. }
  1697. CString _tagXMLEntitys::Entity2Ref( LPCTSTR str )
  1698. {
  1699. CString s;
  1700. if( str )
  1701. {
  1702. int nEntityCount = GetEntityCount(str);
  1703. if( nEntityCount == 0 )
  1704. return CString(str);
  1705. int len = _tcslen(str) + nEntityCount*10 ;
  1706. LPTSTR sbuf = s.GetBufferSetLength( len+1 );
  1707. if( sbuf )
  1708. Entity2Ref( str, sbuf, len );
  1709. }
  1710. return s;
  1711. }
  1712. CString XRef2Entity( LPCTSTR estr )
  1713. {
  1714. return entityDefault.Ref2Entity( estr );
  1715. }
  1716. CString XEntity2Ref( LPCTSTR str )
  1717. {
  1718. return entityDefault.Entity2Ref( str );
  1719. }
  1720. /*
  1721. #define MASKBITS 0x3F
  1722. #define MASKBYTE 0x80
  1723. #define MASK2BYTES 0xC0
  1724. #define MASK3BYTES 0xE0
  1725. #define MASK4BYTES 0xF0
  1726. #define MASK5BYTES 0xF8
  1727. #define MASK6BYTES 0xFC
  1728. typedef unsigned short Unicode2Bytes;
  1729. typedef unsigned int Unicode4Bytes;
  1730. void UTF8Encode2BytesUnicode(std::vector< Unicode2Bytes > input,
  1731. std::vector< byte >& output)
  1732. {
  1733. for(int i=0; i < input.size(); i++)
  1734. {
  1735. // 0xxxxxxx
  1736. if(input[i] < 0x80)
  1737. {
  1738. output.push_back((byte)input[i]);…