WAP之家:为您提供最全最新的WAP技术,CP.SP.3G等行业资讯。 WAP之家交流论坛全新开放 点击进入>>
WAP资讯 | 3G动态 | SP动态 | 运营商动态 | 内容商动态 | 制造商动态 | 论坛讨论>> 每次自动访问
WAP技术 | WAP源码 | 手机编程 | 手机源码 | 无线技术 | J2ME技术 | 手机软件 添加到收藏夹
IVR技术 | SP资料 | SMS MMS技术 | 商业方案 | IVR下载 | 书籍教程 | 工具软件 语言:繁體中文

WAP之家技术文章J2ME技术进阶教程实例教您KXML:J2ME中XML语法分析的利器

实例教您KXML:J2ME中XML语法分析的利器
作者:空中网  来源:空中网  发布时间:2005-8-6 9:12:20
Enhydra的KXML是一个只占很小存储空间的XML语法分析程序,对于J2ME应用程序非常适合。它有一个非常独特的DOM操作方法和被称为Pull的语法分析方法。

我最近一直在开发一个用于J2ME设备的多人游戏项目。在这个应用程序中,服务器和设备之间的通讯原来被编码成由"&"分隔的键值对,这样从服务器检索变量会很快,但是当我开始处理更复杂的数据结构和嵌套的数据结构时,我发现这种方法并不适用。在这种情况,它会变得很难写数据并且容易出错。

  为了解决这问题,我决定使用XML重新编写应用程序的数据传输部分。对于我来说,XML是一个自然而然的选择,不仅仅因为我已经使用它在以前的一个项目中编写了通过网络向applet中传送信息的程序,而且因为XML确实很容易调试和编写。当然,它还让你使用一种很丰富的格式来结构化这些数据。然而,让我意想不到的是我竟为我的编程工具箱找到一颗珍贵的宝石。

  KXML是一个被设计用于J2ME设备的简化类库,虽然它也可以被用于其它需要小型XML语法分析程序的环境,比如Applet。KXML是一个Enhydra维护的项目,支持下面的性能:

1、支持XML名称空间

2、用"松散"模式分析HTML或其它SGML格式

3、占用很少的存储空间(21 kbps)

4、基于Pull的分析

5、支持XML写操作

6、可选的DOM支持

7、可选的WAP支持

  在本文中,我将详细说明其中的一些特点,尤其是Pull分析和DOM操作,而且我将告诉你如何检查KXML在内存中操作的效果。

使用XML工作

  有两个常见的使用XML工作的方法:操作DOM或者捕捉语法分析事件。操作DOM是一个与XML相互作用的简单方法,通常这个XML是一棵完整的XML树,被解析成一个存放在存储器中的节点结构,你可以遍历这棵树。它非常简单易用,但是因为整棵树存在于存储器中造成存储器的负担。

  第二种方法在捕捉语法分析事件中,每当语法分析程序遇到数据中的特定结构,它就会遍历XML数据,然后把结果发回前面注册的一个事件监听器中。比如说,当语法分析程序遇到一个起始标记,如<html>,那么事件监听器将接收一个事件,通知它这个情况,并且向它传递任何所需的信息。实现这种策略的语法分析程序被称为push语法分析程序,因为这个语法分析程序把事件"推入"一个监听器中。

  KXML支持DOM语法分析和操作,但是不支持push语法分析。取而代之,它使用一种稍微不同的称为"Pull"的分析方法。与push语法分析相反,Pull语法分析让程序员从语法分析程序中"拉"出下一个事件。在push语法分析中,你必须维护你正在分析的当前数据的状态,然后基于传送到监听器的事件,恢复任何以前的状态,并且当你转换到一个不同的状态时保存新的状态。Pull语法分析使处理状态改变更加容易,因为你可以发送分析器到不同的函数,维护它们自己的状态变量。

Pull语法分析

  让我们来研究一个例子,看看KXML如何做一个Pull语法分析程序。演示程序名为KXMLDemo_Pull。它将使用一个Pull语法分析程序查看一个包含通讯录信息的文件。下面给出源代码中比较重要的几行,我还给出了注释。

1.XmlParser parser = null;
2......
3.parser = new XmlParser( new InputStreamReader( 1this.getClass().getResourceAsStream(resfile_name) ));


第三行创建了一个XmlParser,把它传到一个InputStream中。这个语法分析程序反复调用,直到出现END_DOCUMENT事件。

1.while ( (event = parser.read()).getType() != Xml.END_DOCUMENT ) {
2. ...
3.if (name != null && name.equals("address")) {
4. ...
5. parseAddressTag( parser );


第三行判断事件是否以一个<address>标记开始,第五行传送语法分析器到控制语法分析程序的"parseAddressTag"。

1.while ((event = parser.peek()).getType() != Xml.END_DOCUMENT) {
2....
3. if (type == Xml.END_TAG && name.equals("address")) {
4. return;
5. }
6.... 
7. ParseEvent next = parser.read();
8. 
9. // if it's not a text event then skip it
10. if (next.getType() != Xml.TEXT) {
11. continue;
12. }
13....
14. System.err.println(name + ": " + text);


上面的这段代码在"parseAddressTag"中循环,直到找到与<address>对应的终止标记。如果它遇到其它任何标记,那么标记名和标记内容就会被打印到控制台上。因此,如果找到标记<name>Robert Cadena</name>,你将看到下面的控制台输出:

name: Robert Cadena


一旦找到<address>的终止标记(8- 10行),控件被返回调用函数,然后又开始查找<address>。

如你所见,使用Pull语法分析程序非常容易,并且能够传送语法分析程序到另一个函数,然后在文档中查找元素。你并不局限于分析资源文件;你还可以使用HttpConnection把这个函数传递到http InputStream。这把你从读取InputStream、保存内容、分析内容等操作中解放了出来,一切都由KXML为你完成。

DOM处理

Pull语法分析特别适用于当你需要维护非常小的存储空间的时候,因为发出事件的文档只有一部分存在于内存中。换句话说,如果你感兴趣的特定数据段是文档中部的几百个字节,那么前面的几百个字节就不必保存在内存中了。

但是如果你能够节省一些内存,你可以使用另一个版本的KXML语法分析程序,它包含对DOM的支持。 DOM是保存在内存中的整个文档树,每个标记都被分离成节点(Node)对象。 你可以遍历这个文档树,然后根据需要取得数据。

工程中的另一个MIDlet,KXMLDemo_dom,做了同样的事情。它读取一个通讯录,然后把内容打印到控制台,但是这次它使用了DOM。下面给出源代码中比较重要的几行.

1.Document doc = new Document();
2....
3.parser = new XmlParser( isr );
4.doc.parse( parser );


第一行创建了一个文档,保存XML树。第三行从一个名为isr的InputStreamReader中创建一个KXML语法分析程序。第四行传送这个语法分析程序到文档,然后让文档开始分析。XML被递归分析,直到到达文档的结尾。当分析调用退出时,整个文档被装入内存,这时你就可以操作它了。

1.Element root = doc.getRootElement();
2.int child_count = root.getChildCount();
3....
4.for (int i = 0; i < child_count ; i++ ) {
5....
6. Element kid = root.getElement(i);
7.
8. if (!kid.getName().equals("address")) {
9. continue;
10. }


[1] [2]  下一页

[] [返回上一页] [打 印]
文章评论

用户名: 查看更多评论

分 值:100分 85分 70分 55分 40分 25分 10分 0分

内 容:

         (注“”为必填内容。) 验证码: 验证码,看不清楚?请点击刷新验证码