惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Help Net Security
博客园 - Franky
GbyAI
GbyAI
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
爱范儿
爱范儿
IT之家
IT之家
酷 壳 – CoolShell
酷 壳 – CoolShell
aimingoo的专栏
aimingoo的专栏
博客园_首页
MongoDB | Blog
MongoDB | Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Recent Announcements
Recent Announcements
Scott Helme
Scott Helme
有赞技术团队
有赞技术团队
M
MIT News - Artificial intelligence
C
CERT Recently Published Vulnerability Notes
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Jina AI
Jina AI
F
Fortinet All Blogs
N
Netflix TechBlog - Medium
L
LangChain Blog
L
LINUX DO - 最新话题
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
H
Hacker News: Front Page
MyScale Blog
MyScale Blog
P
Palo Alto Networks Blog
G
Google Developers Blog
Google DeepMind News
Google DeepMind News
AI
AI
T
Troy Hunt's Blog
Microsoft Azure Blog
Microsoft Azure Blog
阮一峰的网络日志
阮一峰的网络日志
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Vercel News
Vercel News
Microsoft Security Blog
Microsoft Security Blog
罗磊的独立博客
S
Secure Thoughts
大猫的无限游戏
大猫的无限游戏
博客园 - 叶小钗
人人都是产品经理
人人都是产品经理
Blog — PlanetScale
Blog — PlanetScale
博客园 - 司徒正美
Apple Machine Learning Research
Apple Machine Learning Research
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 三生石上(FineUI控件)
S
Security @ Cisco Blogs
Cloudbric
Cloudbric
E
Exploit-DB.com RSS Feed
Attack and Defense Labs
Attack and Defense Labs

博客园 - shipfi

asp.net中的AJAX编程-异步网络调用 asp.net中的AJAX编程-Ajax服务器扩展 asp.net中的AJAX编程-Javascript语法补充 asp.net中的AJAX编程-ASP.NET AJAX框架 asp.net问题点集合 asp.net学习之ado.net(无连接模式中的DataAdapter) asp.net学习之ado.net(连接模式访问) asp.net学习之DataList控件 asp.net学习之Repeater控件 asp.net学习之扩展GridView asp.net学习之GridView事件、GridViewRow对象 asp.net学习之GridView七种字段 asp.net学习之GridView asp.net学习之再论sqlDataSource asp.net学习之SqlDataSource asp.net学习之 数据绑定控件--表格绑定控件 asp.net学习之 数据绑定控件--List数据绑定控件 asp.net学习之数据绑定控件、数据源控件概述 理解T-SQL: 存储过程 - shipfi - 博客园
CMarkup的改进 - shipfi - 博客园
shipfi · 2010-11-29 · via 博客园 - shipfi

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

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

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

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

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

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

 改写后的代码如下所示:

 1 bool CMarkup::FindElem( MCD_CSTR szName )
 2 {
 3     if ( m_nDocFlags & MDF_WRITEFILE )
 4         return false;
 5     if ( m_pElemPosTree->GetSize() )
 6     {
 7         // Change current position only if found
 8         PathPos path( szName, false );
 9         if(path.IsAbsolutePath()) {   /* 绝对路径查找时,XML定位到开始位置 */
10             ResetPos();
11         }
12         int iPos = x_FindElem( m_iPosParent, m_iPos, path );
13         if ( iPos )
14         {
15             // Assign new position
16             x_SetPos( ELEM(iPos).iElemParent, iPos, 0 );
17             return true;
18         }
19     }
20     return false;
21 }

 1 int CMarkup::x_FindElem( int iPosParent, int iPos, 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     //
 6     if ( ! path.ValidPath() )
 7         return 0;
 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 
13     if ( iPos )
14         iPos = ELEM(iPos).iElemNext;
15     else
16         iPos = ELEM(iPosParent).iElemChild;
17 
18     // Finished here if pPath not specified
19     if ( ! path.IsPath() )
20         return iPos;
21 
22     // Search
23     MCD_PCSZ strTmp;
24     int iParent = iPos;
25     int iOldPos = 0;
26     TokenPos token( m_strDoc, m_nDocFlags );
27     if(path.IsAbsolutePath() || path.IsAnywherePath())   /*  取得查找的路径, 删除查找字符串前面的 '/' 符号 */
28         strTmp = path.GetWordAndInc();
29     while ( iPos )
30     {
31         // Compare tag name
32         token.m_nNext = ELEM(iPos).nStart + 1;
33         token.FindName(); // Locate tag name
34         if ( token.Match(strTmp) )
35         {
36             if (path.IsAtPathEnd())   /*  针对绝对路径查找,查找到最后一个Token时返回 */
37             {    
38                 return iPos;   /*  匹配成功 */
39             }
40             else
41             {
42                 path.IncChar();
43                 strTmp = path.GetWordAndInc();   /*  针对绝对路径查找,剥离一个路径。如 [ROOT/ITEMS/ITEM] →[ITEMS/ITEM]  */
44                 iPos = ELEM(iPos).iElemChild;
45                 continue;
46             }
47         }
48         else {
49              path.IncChar();
50              iOldPos = iPos;
51              iPos = ELEM(iPos).iElemChild;  /* 当前节点无法匹配,进入子节点进行匹配 */
52              if(iPos)
53                   continue;
54              else
55                   iPos = iOldPos;
56              if( path.IsAtPathEnd() ) 
57                   iPos = ELEM(ELEM(iPos).iElemParent).iElemNext;  /* 子节点无法匹配,向邻居节点进行匹配 */
58              continue;
59         }
60         iPos = ELEM(iPos).iElemNext;
61     }
62     return 0;
63 
64 }

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