• 软件测试技术
  • 软件测试博客
  • 软件测试视频
  • 开源软件测试技术
  • 软件测试论坛
  • 软件测试沙龙
  • 软件测试资料下载
  • 软件测试杂志
  • 软件测试人才招聘
    暂时没有公告

字号: 小 中 大 | 推荐给好友 上一篇 | 下一篇

SAX编程入门

发布: 2007-7-01 18:47 | 作者: admin | 来源: | 查看: 16次 | 进入软件测试论坛讨论

领测软件测试网 SAX编程入门

作者: 常明 写作日期:2000-4-26



SAX其实就是(Simple Application interface for XML),这个接口规范是XML分析器和XML处理器提供的较XML更底层的接口。它能提供应用以较大的灵活性。

SAX诞生是在XML-DEV讨论组上,提出它的原因是有一些情况不适用DOM接口,而且DOM实现太大而且比较慢。

SAX是一种事件驱动的接口,它的基本原理是,由接口的用户提供符合定义的处理器,XML分析时遇到特定的事件,就去调用处理器中特定事件的处理函数。一般SAX都是JAVA的接口,但其实C++也可以用SAX接口,但C++的分析器比较少。

开发者主要关心的就是,如果我用一个SAX接口的XML分析器或处理器,我需要做些什么呢?那么,下面我们就看一下程序怎么写吧!

SAX需要用户提供一下几个处理器类的实现:

DocumentHandlerXML:文件事件的处理器;

DTDHandler:DTD中事件的处理器;

ErrorHandler:出错处理器。

写程序就是以下这么几步了:

首先需要从这几个类继承出自己的子类,
重载其中自己感兴趣的事件的处理方法。
向分析器,注册此处理器类,其实告诉分析器使用你的处理器。
启动分析器。
下面是我抓来的一个例子(既然有现成的,自己写好象比较浪费了:PP),这个例子中的PrettyPrint类就是一个继承DocumentHandler的实现类,大家可以看到PrettyPrint选择实现了开始元素、结束元素、字符数据、处理指令这样几个事件,最后的结果就是把以不同深度的缩进表示元素的层次的形式把XML输出。

值得注意的是,在处理函数的参数中包含了与此事件相关的重要信息,处理函数其实就是对这些数据的处理。比如开始元素事件的参数中就会有元素名,属性列表的信息。


void PrettyPrint::startElement(const XMLCh* const  name AttributeList& attributes)
{
indent++; // A new element started, //it should be indented one
// level further than the current level
int i;
for(i = 0; i < indent; i++) outStrm << "\t";
outStrm << "<" << name;
unsigned int len = attributes.getLength();
for (unsigned int i = 0; i < len; i++)
{  
  outStrm << " " << attributes.getName(i) <<  
  "=\"" << attributes.getValue(i) <<  
  "\"";
}
outStrm << ">";
}

void PrettyPrint::endElement(const XMLCh* const name)
{ int i; for(i = 0; i < indent; i++)
outStrm << "\t"; outStrm << "</" <<  
name << ">";
indent--;
}

void PrettyPrint::characters(const XMLCh* const chars, const unsigned int  
length)
{
for (unsigned int index = 0; index < length; index++)
{
  switch (chars[index])
  {  
   case chAmpersand : outStrm << "&"; break;
   case chOpenAngle : outStrm << "<"; break;  
   case chCloseAngle: outStrm << ">"; break;  
   case chDoubleQuote : outStrm << """; break;
   default: outStrm << chars[index];
            break;
   }
}
}

void PrettyPrint::processingInstruction(const XMLCh* const target, const  
XMLCh* const data)
{
int i; for(i = 0; i < indent; i++) outStrm << "\t";  
outStrm << "<?" << target; if (data) outStrm  
<< " " << data; outStrm << "?>\n";

}

看过这个例子,大家应该是比较清楚如何写SAX的处理器了。具体的SAX接口可以在你要用的分析器的定义中找到,JAVA中就是interface或class,C++中可能就是类的定义。写好以后就要调用Parser类的以下函数,将处理器设到parser内去:

public abstract void setDTDHandler (DTDHandler handler);
public abstract void setDocumentHandler (DocumentHandler handler);

public abstract void setErrorHandler (ErrorHandler handler);

...

此外SAX接口里有另外的几个由分析器回调的处理器,他们的用法下面一一讲一下:

InputSource:这个处理器的作用是控制XML文件的输入,这样输入就可以有更多种选择,可以来自文件系统,或Web服务器,甚至数据库。

EntityResolver:解析外部实体用,分析器通过它得到外部实体。

Locator:定位器,作用是分析器用来在文件中定位的。作用之一就是报错时能得到错误的位置。

这几个的详细用法,如果需要我以后会写文章讲细一些。

DOM也是XML的数据接口,读到这里,有些读者可能会问,SAX和DOM的关系是怎样的呢? Don Park的SAXDOM实现了从SAX接口实现DOM模型,从这样一个工具我们可以看出SAX是比DOM更低层的接 口,有了SAX,我们完全可以自己构造出DOM。DOM好用一些,为什么还要提出SAX呢?DOM模型的建立是分 析完整个XML文件后才能完成,对于某些特殊情况用DOM实现就不太现实,如XML文件特别大时,在内存建立 一棵它的DOM树是不可想象的,还有当对于动态生成的XML,还没有完成时,我们就需要知道里面有什么, 这时也不能用DOM。另外SAX运行很快,对于一些简单的任务,用它效率比较高。所以DOM和SAX各有千秋, 可以在开发中互补。


延伸阅读

文章来源于领测软件测试网 https://www.ltesting.net/


关于领测软件测试网 | 领测软件测试网合作伙伴 | 广告服务 | 投稿指南 | 联系我们 | 网站地图 | 友情链接
版权所有(C) 2003-2010 TestAge(领测软件测试网)|领测国际科技(北京)有限公司|软件测试工程师培训网 All Rights Reserved
北京市海淀区中关村南大街9号北京理工科技大厦1402室 京ICP备10010545号-5
技术支持和业务联系:[email protected] 电话:010-51297073

软件测试 | 领测国际 | ISTQB | ISTQB官网 | TMMi | TMMi认证 | 国际软件测试工程师认证 | 领测软件测试网