<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      XML文件解析器TXml

      前幾天看了開源的XML文件解析器TinyXml,它是怎么實現(xiàn)解析的沒怎么看懂,于是決定自己實現(xiàn)一個,反正最近不忙。先命名為TXml。現(xiàn)在完成了解析和查詢功能,全部代碼加起來不到1000行,將會繼續(xù)完善它。源碼必共享

      先簡單說一下我的思路:

      1:讀取XML文件信息,并存入一個字符數(shù)組中;

      2:遍歷數(shù)組,將數(shù)組解析成一棵樹;

      3:以路徑的方式查詢和按屬性查詢;

      這個解析器最麻煩的地方就在怎么將字符數(shù)組解析成一顆樹。我們先看一下一個簡單XML文件,他包括文件頭、節(jié)點、節(jié)點名稱及節(jié)點值、屬性名稱及屬性值,子節(jié)點、父節(jié)點、注釋等。

      <?xml version="1.0" encoding="utf-8" ?>
      <!--注釋-->
      <Items>
        <item name="chentaihan">89757</item>
      </Items>

      簡單介紹一下解析的實現(xiàn),不太好說清楚,看代碼可能更容易理解一些。遞歸實現(xiàn),每次都從一個節(jié)點開始解析,就是從字符“<”開始,到字符“>”結(jié)束,字符<后面就是節(jié)點的名稱,之后的就是節(jié)點屬性,字符>后一個字符如果不是<,那就是節(jié)點的值,如果是字符<,可能是子節(jié)點也可能是這個節(jié)點結(jié)束了。遇到字符<開始遞歸,空格和注釋直接被PASS。大致代碼如下:

      const char* TXmlParser::ParseContent(const char* p,XmlNode* baseNode)
      { 
          if(p==NULL || !*p) 
              return NULL; 
          if(*p=='<')//開始一個節(jié)點
          {
              bool isNote;
              p=SkipNote(p,isNote);//跳過注釋
              if(isNote) {//是注釋
                  ParseContent(p,baseNode); 
                  return NULL;
              } 
              if(*p=='/')//結(jié)束節(jié)點
              {
                  while(p!=NULL && *p && *p!='>')
                  {
                      p++;
                  } 
                  ++p=SkipWhiteSpace(p);
                  ParseContent(p,baseNode->parent);//新節(jié)點
              }else{ //節(jié)點屬性  
                  string name;
                  while(p!=NULL && *p && *p!='>' && *p!=' ' && *p!='/')
                  {
                       name.push_back(*p++); 
                  }
                  XmlNode* node=new XmlNode(name,baseNode);
                  baseNode->AppendNode(node);
      
                  if(*p=='>')
                  {
                      ++p=SkipWhiteSpace(p); 
                      ParseContent(p,node);//新節(jié)點
                  }else{
                      p=GetAttr(p,node);
                      if(*p=='/')
                      {
                          while(p!=NULL && *p && *p!='<')
                              p++;
                          ParseContent(p,baseNode);//新節(jié)點
                      }else{
                          ++p=SkipWhiteSpace(p);  
                          ParseContent(p,node);//新節(jié)點
                      }
                  }  
              }
          }else{//節(jié)點的值 
              GetNodeValue(p,baseNode);
          } 
      }

      按路徑的方式查詢。利用兩個數(shù)組實現(xiàn),假設(shè)這兩個數(shù)組分別為A,B;第一次查詢將結(jié)果存入數(shù)組A,將A作為數(shù)據(jù)源,將查詢結(jié)果存入B,清除A中的數(shù)據(jù),將B作為數(shù)據(jù)源,將查詢結(jié)果存入A,反復(fù)進(jìn)行,最后A,B中有一個就是查詢結(jié)果。當(dāng)然也可以用遞歸實現(xiàn),我們都知道遞歸太深容易爆線程棧,且性能低。

      按屬性查詢。同樣沒有用遞歸實現(xiàn),有個經(jīng)常出現(xiàn)的面試題:按層序打印一個棵樹。那么這里也是按層序查找,就是利用一個隊列,按根節(jié)點、根節(jié)點的直接子節(jié)點進(jìn)棧,一個個匹配,不匹配就出隊列。

      //根據(jù)屬性查詢--利用隊列按層序查詢
      XmlNode* XmlNode::SelectSingleNodeByAttr(const string& attrName,const string& attrValue,XmlNode* node)
      {  
          if(node==NULL)
              return NULL; 
          if(node->attribute!=NULL && (*node->attribute)[attrName]==attrValue)
          { 
              return node;
          } 
          queue<XmlNode*> list; 
          for(int i=node->ChildCount()-1;i>=0;i--)
          {
              list.push((*node->childNodes)[i]); 
          }
      
          while(list.size()>0)
          {
              XmlNode* tmpNode=list.front();
              if(tmpNode->attribute!=NULL && (*tmpNode->attribute)[attrName]==attrValue)
              { 
                  return tmpNode;
              }
              for(int i=tmpNode->ChildCount()-1;i>=0;i--)
              {
                  list.push((*tmpNode->childNodes)[i]); 
              }
              list.pop();
          } 
          return NULL;
      }

      看了按屬性查找,我們就很容易知道,C#中ConfigurationManager讀取配置文件的大致實現(xiàn),因為配置文件很簡單,就是一個節(jié)點下面有多個節(jié)點,完全可以這樣實現(xiàn),根節(jié)點基本可以無視,直接就是一個字典,KEY存key的值,VALUE存value的值,查找的時間復(fù)雜度就是O(1)。

      簡單測試:

      #include "XmlDocument.h"
       
      int main()
      {
          {    
              XmlDocument doc;
              doc.Load("test.txt");   
              cout<<"XML頭部:"<<doc.Head().c_str()<<endl;
              cout<<"顯示全部學(xué)生成績:" ;
              doc.ShowXML(doc);  
              cout<<endl;
              vector<XmlNode*> vect;
              doc.SelectNodes("students/student/courses/course",vect);
               
              XmlNode* node=doc.SelectSingleNode("students/Student/courses/course/Course"); 
      
              if(node!=NULL)
              {
                  node->ShowXML(*node); 
                  cout<<"name:"<<node->Name().c_str()<<endl;
                  cout<<"屬性:";
                  node->ShowAttr() ; 
                  cout<<endl;
                  cout<<"value:"<<node->Value().c_str()<<endl;
                  cout<<"ChildCount:"<<node->ChildCount()<<endl<<endl;
                  
                   XmlNode::Iterator iter=node->begin();
                  while(iter!=node->end())
                  { 
                      cout<<"name:"<<(*((iter)._Ptr))->Name().c_str() <<endl;
                      cout<<"value:"<<(*((iter)._Ptr))->Value().c_str() <<endl; 
                      iter++;
                  }  
              }   
              cout<<"查找name=‘英文’的節(jié)點:"<<endl;
              XmlNode* node2=doc.SelectSingleNodeByAttr("name","英文");
              if(node2!=NULL){
                  node2->ShowXML(*node2); 
              }
          }
          
          system("pause");
          return 0;
      }

      運行結(jié)果如下:

       

      未完...待續(xù)...功能將會更加豐富,我們都值得期待!

      posted @ 2013-04-11 15:58  古文觀芷  閱讀(6392)  評論(3)    收藏  舉報
      主站蜘蛛池模板: 亚洲国产成人久久综合一区77| 香蕉av777xxx色综合一区| 男女激情一区二区三区| 亚洲精品一区二区三区蜜臀 | 四虎国产精品久久免费精品| 国产AV影片麻豆精品传媒| 日本三级香港三级三级人妇久 | 欧美日本在线一区二区三区| 色噜噜噜亚洲男人的天堂| 温州市| 九九热免费在线视频观看| caoporn成人免费公开| 亚洲熟妇无码爱v在线观看| 看免费的无码区特aa毛片| 亚洲欧美日韩在线码 | 亚洲欧美综合人成在线| 国产精品污一区二区三区| 国产亚洲人成网站在线观看| 亚洲成人四虎在线播放| 国产伦精品一区二区三区| 久久精品国产亚洲av忘忧草18| gogogo高清在线播放免费| 国产一国产看免费高清片| 久久综合亚洲鲁鲁九月天| 蜜臀av黑人亚洲精品| 亚洲av激情久久精品人| 97在线视频人妻无码| 色综合伊人色综合网站| 日韩精品无码区免费专区| 欧美性受xxxx黑人猛交| 亚洲精品一区二区三天美| 五月天免费中文字幕av| 日韩有码中文在线观看| 农村老熟女一区二区三区| 免费99视频| 亚洲超碰97无码中文字幕| 日韩精品一区二区三区四| 视频一区视频二区视频三| 884aa四虎影成人精品| 国产精品成人午夜福利| 边坝县|