当前位置:首页>> iPhone wap浏览器之预备篇

iPhone wap浏览器之预备篇

发布时间:2018-03-18作者:智汇小新

  在笔者的上一篇文章《玩转iPhone网络通讯之BSD Socket篇》中,笔者试图在iPhone平台上利用BSD Socket搭建了一个同时兼容TCP/IP和HTTP协议进行通讯的框架,而在接下来的几篇文章里,笔者将进一步完善这个网络通讯的引擎并利用这个引擎写一个简易的wap浏览器。

  在iPhone的safari浏览器上并不支持WML的解析,尽管笔者也认为WML这种抱残守旧的技术被淘汰是迟早的事,但WML作为XML结构的一个“变种”进行学习还是不错的。

  最近浏览器技术很热,热得笔者都摸不着头脑,前段时间金山的雷军同志也投资UCWeb,尽管笔者并不觉得浏览器技术有什么高深的技术含量抑或可进行投资的价值,其实浏览器充其量是个客户端,但是既然人家大牛看好,那笔者研究研究也不无益处,或许看完本文读者也可以拿着自己的产品去找雷军同志投资一把了:)

  闲话少话,言归正传。

  上面说了,WML是XML结构的一个“变种”或者说特例,既然是特例那么就可以把它当成XML来进行解析。那么做一个浏览器的任务流程就清晰了,如下:

  封装BSD Socket进行HTTP请求。

  将请求到的WML页面解析成XML数据结构。

  渲染需要在界面上显示的WML标签(英文名tag)。

  将渲染后的WML标签显示在界面上(UIView)。

  其中第一条在笔者的前一篇文中《玩转iPhone网络通讯之BSD Socket篇》已经进行了初步的编写,当然笔者还会在下面的文章中进一步完善。

  这篇文章中着重讲解WML的解析,因为WML是XML数据的特例,解析WML也就意味这解析XML。

  说到解析XML,iPhone为程序员提供了很多工具比如NSXMLParser,这个类的接口定义如下:

  @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

  从接口的定义中大致可以知道,这个类解析XML是采用SAX模式(Simple API for XML),而SAX是基于事件驱动的,其基本工作流程是分析XML文件流数据,每当发现一个新的元素时,就会产生一个对应的事件,并调用相应的用户处理函数。在iPhone上苹果公司采用了delegate模式,每发现一个新的元素时,就会调用相应的委托接口进行XML标签的处理。

  利用SAX模式解析XML占用内存少、速度快,但用户需要把解析到的XML标签自己组合成一个树状结构,从而使程序处理比较复杂。

  而对WML浏览器来说,尽管其tag并不是特别多,但是如果想完整的支持WML的tag也是一件比较枯燥的事情。所以,笔者这里采用DOM(Document Object Model)模式来解析XML文件。DOM模式在分析XML文件时,一次性的将整个XML文件流进行分析,并在内存中形成对应的树结构,同时,向用户提供一系列的接口来访问和编辑该树结构。这种方式占用内存大,速度往往慢于SAX模式,但可以给程序员提供一个面向对象的访问接口,较为方便。

  XML语言的全称是可扩展标识语言(eXtensible Markup Language),具体含义顾名思义就知道了。所谓“可扩展”,那是因为HTML等语言的不可扩展,在XML里的标签都是可以自定义的,比如WML利用XML语言自定义了一套tag,于是就有了无线wap规范。

  XML的可扩展性是指在相应的规范和标准上的扩展。首先格式要符合XML的基本要求,比如第一行要有声明,标签的嵌套层次必须前后一致等等,符合这些要求的文件,就算是一个合格的XML文件,称为Well-formatted。其次,XML文档因其内容的不同还必须在语义上符合相应的标准,这些标准由相应的“DTD文件”或者“Schema文件”来了定义,符合了这些定义要求的XML文件,称作Valid。

  笔者在本文中采用了开源的TinyXML解析器,这个解析器不会用相应的DTD文件对XML文件进行校验,但它的体积很小,只包含两个*.h文件和四个*.cpp文件。

  TinyXML是个开源的项目,更多详细的信息可以参考http://www.grinninglizard.com/tinyxml/index.html。

  下载文件包后,把相应的文件导入到项目工程中,如下图:

  

  图1

  其中tinyxml.h文件包含了全部的声明,在项目中只需要包含这个文件即可。

  Tinyxml.h中定义了很多结构,如下

  class TiXmlNode : public TiXmlBase

  {

  friend class TiXmlDocument;

  friend class TiXmlElement;

  …

  }

  这些类对应XML中的树状结构,拿下面的XML文档为例:

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

  《!-example--》

  《food》

  《name》bread《/name》

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

  《description》made in China《/description》

  《/ food 》

  其中整个XML文档用类TiXmlDocument表示,《food》、《name》、《price》、《description》等各自对应一个类TiXmlElement,XML文档的第一行对应类TiXmlDeclaration,第二行对应类TiXmlComment,文本“example”对应类TiXmlText,unit则是元素price的一个TiXmlAttribute属性。

  把TinyXML包导入到项目后,新建一个XMLParserEx.h文件和一个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文件实现如下:

  #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);

  }

公司简介

宜科(天津)电子有限公司是中国工业自动化的领军企业,于2003年在天津投资成立,销售和服务网络覆盖全国。作为中国本土工业自动化产品的提供商和智能制造解决方案的供应商,宜科在汽车、汽车零部件、工程机械、机器人、食品制药、印刷包装、纺织机械、物流设备、电子制造等诸多领域占据领先地位。宜科为智慧工厂的整体规划实施提供自系统层、控制层、网络层到执行层自上而下的全系列服务,产品及解决方案涵盖但不局限于云平台、MES制造执行系统、工业现场总线、工业以太网、工业无线通讯、机器人及智能设备组成的自动化生产线、自动化电气控制系统集成、智能物流仓储系统等,以实现真正智能化的生产制造,从而带来生产力和生产效率的大幅提升,以及对生产灵活性和生产复杂性的管理能力的大幅提升。多年来,宜科以创新的技术、卓越的解决方案和产品坚持不懈地为中国制造业的发展提供全面支持,并以出众的品质和令人信赖的可靠性、领先的技术成就、不懈的创新追求,在业界独树一帜。帮助中国制造业转型升级,加速智能制造进程,成为中国工业4.0智慧工厂解决方案当之无愧的践行者。

更多详情>>

联系我们

  • 联系人:章清涛
  • 热线:18611695135
  • 电话:
  • 传真:
  • 邮箱:18210150532@139.com

Copyright © 2015 ilinki.net Inc. All rights reserved. 智汇工业版权所有

电话:010-62314658 邮箱:service@ilinki.net

主办单位:智汇万联(北京)信息技术有限公司

京ICP备15030148号-1