免费色播,亚洲国产欧美国产第一区二区三区,毛片看,日本精品在线观看视频,国产成人精品一区二区免费视频,日本黄色免费网站,一级毛片免费

iPhone wap瀏覽器之預(yù)備篇

來源:網(wǎng)絡(luò)

點(diǎn)擊:1945

A+ A-

所屬頻道:新聞中心

關(guān)鍵詞: iPhone,wap瀏覽器,XML

      在筆者的上一篇文章《玩轉(zhuǎn)iPhone網(wǎng)絡(luò)通訊之BSD Socket篇》中,筆者試圖在iPhone平臺(tái)上利用BSD Socket搭建了一個(gè)同時(shí)兼容TCP/IP和HTTP協(xié)議進(jìn)行通訊的框架,而在接下來的幾篇文章里,筆者將進(jìn)一步完善這個(gè)網(wǎng)絡(luò)通訊的引擎并利用這個(gè)引擎寫一個(gè)簡易的wap瀏覽器。

      在iPhone的safari瀏覽器上并不支持WML的解析,盡管筆者也認(rèn)為WML這種抱殘守舊的技術(shù)被淘汰是遲早的事,但WML作為XML結(jié)構(gòu)的一個(gè)“變種”進(jìn)行學(xué)習(xí)還是不錯(cuò)的。

      最近瀏覽器技術(shù)很熱,熱得筆者都摸不著頭腦,前段時(shí)間金山的雷軍同志也投資UCWeb,盡管筆者并不覺得瀏覽器技術(shù)有什么高深的技術(shù)含量抑或可進(jìn)行投資的價(jià)值,其實(shí)瀏覽器充其量是個(gè)客戶端,但是既然人家大??春?,那筆者研究研究也不無益處,或許看完本文讀者也可以拿著自己的產(chǎn)品去找雷軍同志投資一把了:)

      閑話少話,言歸正傳。

      上面說了,WML是XML結(jié)構(gòu)的一個(gè)“變種”或者說特例,既然是特例那么就可以把它當(dāng)成XML來進(jìn)行解析。那么做一個(gè)瀏覽器的任務(wù)流程就清晰了,如下:

      封裝BSD Socket進(jìn)行HTTP請求。

      將請求到的WML頁面解析成XML數(shù)據(jù)結(jié)構(gòu)。

      渲染需要在界面上顯示的WML標(biāo)簽(英文名tag)。

      將渲染后的WML標(biāo)簽顯示在界面上(UIView)。

      其中第一條在筆者的前一篇文中《玩轉(zhuǎn)iPhone網(wǎng)絡(luò)通訊之BSD Socket篇》已經(jīng)進(jìn)行了初步的編寫,當(dāng)然筆者還會(huì)在下面的文章中進(jìn)一步完善。

      這篇文章中著重講解WML的解析,因?yàn)閃ML是XML數(shù)據(jù)的特例,解析WML也就意味這解析XML。

      說到解析XML,iPhone為程序員提供了很多工具比如NSXMLParser,這個(gè)類的接口定義如下:

      @interface NSXMLParser : NSObject {

      @private

      void * _parser;

      id _delegate;

      id _reserved1;

      id _reserved2;

      id _reserved3;

      }

      - (id)initWithContentsOfURL:(NSURL *)url; // initializes the parser with the specified URL.

      - (id)initWithData:(NSData *)data; // create the parser from data

      // delegate management. The delegate is not retained.

      - (id)delegate;

      - (void)setDelegate:(id)delegate;

      - (void)setShouldProcessNamespaces:(BOOL)shouldProcessNamespaces;

      - (void)setShouldReportNamespacePrefixes:(BOOL)shouldReportNamespacePrefixes;

      - (void)setShouldResolveExternalEntities:(BOOL)shouldResolveExternalEntities;

      - (BOOL)shouldProcessNamespaces;

      - (BOOL)shouldReportNamespacePrefixes;

      - (BOOL)shouldResolveExternalEntities;

      - (BOOL)parse; // called to start the event-driven parse. Returns YES in the event of a successful parse, and NO in case of error.

      - (void)abortParsing; // called by the delegate to stop the parse. The delegate will get an error message sent to it.

      - (NSError *)parserError; // can be called after a parse is over to determine parser state.

      @end

      從接口的定義中大致可以知道,這個(gè)類解析XML是采用SAX模式(Simple API for XML),而SAX是基于事件驅(qū)動(dòng)的,其基本工作流程是分析XML文件流數(shù)據(jù),每當(dāng)發(fā)現(xiàn)一個(gè)新的元素時(shí),就會(huì)產(chǎn)生一個(gè)對應(yīng)的事件,并調(diào)用相應(yīng)的用戶處理函數(shù)。在iPhone上蘋果公司采用了delegate模式,每發(fā)現(xiàn)一個(gè)新的元素時(shí),就會(huì)調(diào)用相應(yīng)的委托接口進(jìn)行XML標(biāo)簽的處理。

      利用SAX模式解析XML占用內(nèi)存少、速度快,但用戶需要把解析到的XML標(biāo)簽自己組合成一個(gè)樹狀結(jié)構(gòu),從而使程序處理比較復(fù)雜。

      而對WML瀏覽器來說,盡管其tag并不是特別多,但是如果想完整的支持WML的tag也是一件比較枯燥的事情。所以,筆者這里采用DOM(Document Object Model)模式來解析XML文件。DOM模式在分析XML文件時(shí),一次性的將整個(gè)XML文件流進(jìn)行分析,并在內(nèi)存中形成對應(yīng)的樹結(jié)構(gòu),同時(shí),向用戶提供一系列的接口來訪問和編輯該樹結(jié)構(gòu)。這種方式占用內(nèi)存大,速度往往慢于SAX模式,但可以給程序員提供一個(gè)面向?qū)ο蟮脑L問接口,較為方便。

      XML語言的全稱是可擴(kuò)展標(biāo)識(shí)語言(eXtensible Markup Language),具體含義顧名思義就知道了。所謂“可擴(kuò)展”,那是因?yàn)镠TML等語言的不可擴(kuò)展,在XML里的標(biāo)簽都是可以自定義的,比如WML利用XML語言自定義了一套tag,于是就有了無線wap規(guī)范。

      XML的可擴(kuò)展性是指在相應(yīng)的規(guī)范和標(biāo)準(zhǔn)上的擴(kuò)展。首先格式要符合XML的基本要求,比如第一行要有聲明,標(biāo)簽的嵌套層次必須前后一致等等,符合這些要求的文件,就算是一個(gè)合格的XML文件,稱為Well-formatted。其次,XML文檔因其內(nèi)容的不同還必須在語義上符合相應(yīng)的標(biāo)準(zhǔn),這些標(biāo)準(zhǔn)由相應(yīng)的“DTD文件”或者“Schema文件”來了定義,符合了這些定義要求的XML文件,稱作Valid。

      筆者在本文中采用了開源的TinyXML解析器,這個(gè)解析器不會(huì)用相應(yīng)的DTD文件對XML文件進(jìn)行校驗(yàn),但它的體積很小,只包含兩個(gè)*.h文件和四個(gè)*.cpp文件。

      TinyXML是個(gè)開源的項(xiàng)目,更多詳細(xì)的信息可以參考http://www.grinninglizard.com/tinyxml/index.html。

      下載文件包后,把相應(yīng)的文件導(dǎo)入到項(xiàng)目工程中,如下圖:

      

      圖1

      其中tinyxml.h文件包含了全部的聲明,在項(xiàng)目中只需要包含這個(gè)文件即可。

      Tinyxml.h中定義了很多結(jié)構(gòu),如下

      class TiXmlNode : public TiXmlBase

      {

      friend class TiXmlDocument;

      friend class TiXmlElement;

      …

      }

      這些類對應(yīng)XML中的樹狀結(jié)構(gòu),拿下面的XML文檔為例:

      《?xml version=“1.0” encoding=“utf-8” ?》

      《!-example--》

      《food》

      《name》bread《/name》

      《price unit=”$”》1.5《/price》

      《description》made in China《/description》

      《/ food 》

      其中整個(gè)XML文檔用類TiXmlDocument表示,《food》、《name》、《price》、《description》等各自對應(yīng)一個(gè)類TiXmlElement,XML文檔的第一行對應(yīng)類TiXmlDeclaration,第二行對應(yīng)類TiXmlComment,文本“example”對應(yīng)類TiXmlText,unit則是元素price的一個(gè)TiXmlAttribute屬性。

      把TinyXML包導(dǎo)入到項(xiàng)目后,新建一個(gè)XMLParserEx.h文件和一個(gè)XMLParserEx.cpp文件來封裝XML的處理,頭文件定義如下:

      #ifndef _CC_XMLPARSEREX_H_

      #define _CC_XMLPARSEREX_H_

      #include 《stdio.h》

      #include “tinyxml.h”

      #define INVALID_ID -1

      class XMLParserEx

      {

      public:

      static XMLParserEx* GetInstance();

      static void Destroy();

      void RemoveAll();

      void parsexml(const char* buffer);

      void ElementParser(TiXmlNode* aParent);

      protected:

      XMLParserEx();

      ~XMLParserEx();

      private:

      static XMLParserEx* mInstance;

      };

      #endif

      XMLParserEx.cpp文件實(shí)現(xiàn)如下:

      #include “XMLParserEx.h”

      XMLParserEx::XMLParserEx()

      {

      }

      XMLParserEx::~XMLParserEx()

      {

      RemoveAll();

      }

      XMLParserEx* XMLParserEx::mInstance = 0;

      XMLParserEx* XMLParserEx::GetInstance()

      {

      if (mInstance == 0)

      {

      mInstance = new XMLParserEx();

      }

      return mInstance;

      }

      void XMLParserEx::Destroy()

      {

      if (mInstance)

      {

      delete mInstance;

      mInstance = 0;

      }

      }

      void XMLParserEx::RemoveAll()

      {

      }

      void XMLParserEx::ElementParser(TiXmlNode* aParent)

      {

      if(aParent == NULL)

      return;

      TiXmlNode* aChild = aParent-》FirstChild();

      while(aChild)

      {

      printf(“aChild value = %s\n”,aChild-》Value());

      int t = aChild-》Type();

      if( t == TiXmlNode::ELEMENT)

      {

      TiXmlAttribute* attr = aChild-》ToElement()-》FirstAttribute();

      if(attr)

      {

      TiXmlNode* node = aChild;

      while(node)

      {

      while(attr)

      {

      printf(“attr name = %s, attr value = %s\n”,attr-》Name(),attr-》Value());

      attr = attr-》Next();

      }

      node = node-》NextSiblingElement();

      }

      }

      ElementParser(aChild);

      }

      else if( t == TiXmlNode::TEXT)

      {

      printf(“aChild Value = %s\n”,aChild-》Value());

      }

      aChild = aChild-》NextSibling();

      }

      }

      void XMLParserEx::parsexml(const char* buffer)

      {

      TiXmlDocument* doc = new TiXmlDocument();

      printf(“xmlBuffer len = %d\n”,strlen(buffer));

      printf(“xmlBuffer is = %s\n”,buffer);

      doc-》Parse(buffer,0,TIXML_ENCODING_UTF8);

      TiXmlElement* root = doc-》RootElement();

      printf(“parse xml succeed\n”);

      ElementParser(root);

      }

    (審核編輯: 智匯小新)

    聲明:除特別說明之外,新聞內(nèi)容及圖片均來自網(wǎng)絡(luò)及各大主流媒體。版權(quán)歸原作者所有。如認(rèn)為內(nèi)容侵權(quán),請聯(lián)系我們刪除。