CMarkup的改进

对于使用C++语言,CMarkup由于其灵活、快速的特点,成为很多程序员用来解析XML的一个工具。

但是,由于免费版本不支持XPATH的查找,在Free版本中,当需要在一个XML中定位某个节点时,需要不断的IntoElem,FindElem,很不方便。所以,花了一个下午的时间,特意改写了一个CMarkup类,使其支持以下任意定位和绝对定位的查找:

markup.FindItem("//Item"); / 任意定位 /

markup.FindItem("/ROOT/ITEMS/ITEM"); / 绝对定位 /

主要改写的点在以下两个函数:

CMarkup::FindElem() 和 CMarkup::x_FindElem()

改写后的代码如下所示:
1boolCMarkup::FindElem( MCD_CSTR szName )

2{

3if( m_nDocFlags&MDF_WRITEFILE )

4returnfalse;

5if( m_pElemPosTree->GetSize() )

6{

7//Change current position only if found

8PathPos path( szName,false);

9if(path.IsAbsolutePath()) {/绝对路径查找时,XML定位到开始位置/

10ResetPos();

11}

12intiPos=x_FindElem( m_iPosParent, m_iPos, path );

13if( iPos )

14{

15//Assign new position

16x_SetPos( ELEM(iPos).iElemParent, iPos,0);

17returntrue;

18}

19}

20returnfalse;

21}


1intCMarkup::x_FindElem(intiPosParent,intiPos, PathPos&path )const

2{

3//If pPath is NULL or empty, go to next sibling element

4//Otherwise go to next sibling element with matching path

5//

6if(!path.ValidPath() )

7return0;

8

9//Paths other than simple tag name are only supported in the developer version

10//if ( path.IsAnywherePath() || path.IsAbsolutePath() ) / 原有功能针对绝对定位及任意定位查找时,直接返回. /

11//return 0;

12

13if( iPos )

14iPos=ELEM(iPos).iElemNext;

15else

16iPos=ELEM(iPosParent).iElemChild;

17

18//Finished here if pPath not specified

19if(!path.IsPath() )

20returniPos;

21

22//Search

23MCD_PCSZ strTmp;

24intiParent=iPos;

25intiOldPos=0;

26TokenPos token( m_strDoc, m_nDocFlags );

27if(path.IsAbsolutePath()||path.IsAnywherePath())/取得查找的路径, 删除查找字符串前面的 '/' 符号/

28strTmp=path.GetWordAndInc();

29while( iPos )

30{

31//Compare tag name

32token.m_nNext=ELEM(iPos).nStart+1;

33token.FindName();//Locate tag name

34if( token.Match(strTmp) )

35{

36if(path.IsAtPathEnd())/针对绝对路径查找,查找到最后一个Token时返回/

37{

38returniPos;/匹配成功/

39}

40else

41{

42path.IncChar();

43strTmp=path.GetWordAndInc();/针对绝对路径查找,剥离一个路径。如 [ROOT/ITEMS/ITEM] →[ITEMS/ITEM]/

44iPos=ELEM(iPos).iElemChild;

45continue;

46}

47}

48else{

49path.IncChar();

50iOldPos=iPos;

51iPos=ELEM(iPos).iElemChild;/当前节点无法匹配,进入子节点进行匹配/

52if(iPos)

53continue;

54else

55iPos=iOldPos;

56if( path.IsAtPathEnd() )

57iPos=ELEM(ELEM(iPos).iElemParent).iElemNext;/子节点无法匹配,向邻居节点进行匹配/

58continue;

59}

60iPos=ELEM(iPos).iElemNext;

61}

62return0;

63

64}


以上、一时还有一些没考虑到的情况,不过经过一些简单测试,至少是可以使用的。


原文链接: https://www.cnblogs.com/shipfi/archive/2010/11/29/1891243.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/18070

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月7日 下午6:47
下一篇 2023年2月7日 下午6:47

相关推荐