当前位置:编程学习 > JSP >>

SAX编程入门

答案:SAX编程入门

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



SAX其实就是(Simple Application inte易做图ce 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中就是inte易做图ce或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各有千秋, 可以在开发中互补。


上一个:可扩展的样式语言XSL(Extensible Style Language)
下一个:解析器的使用(JAXP)

CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,